Typescript Partial接口的奇怪行为

3

我在我正在处理的一个代码库中发现了一些代码,看起来完全不正确。下面是我遇到的一个例子。

interface Car {
  make: string
  model: string
}

type SomeType = Partial<Car>

const car: SomeType = {}

if (car === "typescript doesn't complain about this") {
    // This code will never execute..?
}

我错过了什么吗?car永远不会等于一个字符串,对吧?通常情况下,当你试图比较两种没有重叠的不同类型时,TypeScript会提示你并告诉你它总是返回false。如果有任何帮助,将不胜感激!

2个回答

3

Partial<Car>是一种弱类型,因为它的所有属性都是可选的。 TypeScript 2.4添加了一个检查,如果您试图分配类似于string这样的弱类型,它会发出警告,因为没有重叠的属性:

let car: { make?: string, model?: string };
car = {}; // okay
car = "oops"; // error! Type '"oops"' has no properties in common with type 
// '{ make?: string | undefined; model?: string | undefined; }'.

但在 TypeScript 2.4 之前,car = "oops" 是允许的,不会出现错误,因为 "oops" 中没有任何明显的成员(如 lengthtoUpperCase)与 Partial<Car> 冲突。结构上string Partial<Car>。但这种赋值可能是一个错误,弱类型检测警告你注意它。
这种弱类型检测似乎只适用于可赋值性,但对比较运算符没有作用,正如您所注意到的:
if (car === "oops") {  } // no error

microsoft/TypeScript#32627上有一个开放的功能请求,要求更改此项。如果您足够关心这个问题并希望看到它得到改变,您可以前往该问题,给予支持,并可能提供一个令人信服的理由说明为什么这对您很重要。但我怀疑这不会产生太大的影响,因为没有社区参与,也没有迹象表明这将被实现。想必在现实世界的代码中,人们很少遇到这种情况。


所以,就你提出的问题而言,比较运算符从未实现弱类型检测,似乎也没有太多要求改变这种情况的需求。

代码操场链接


有趣。感谢您的详细解答!您的解释确实很合理。我会访问链接的功能请求并进行一些参与。比较运算符的当前行为似乎比有帮助更令人困惑。 - haymez

0

Partial<T> 总是允许类型 {}(当没有提供键时)。

{} 有一些... 怪癖。

它几乎就像使用 any。在 JavaScript 中,几乎每个值都可以分配给类型 {}。因为想想看,它不需要该值具有任何键。任何东西至少都有一些键,所以按结构类型,任何东西都符合此类型。

如果省略 SomeType,则结果将相同:

const car = {}; // now inferred as '{}'

if (car === "typescript doesn't complain about this") {

}

TypeScript不会抱怨它,因为在其眼中,条件运行是可能的(类型重叠,字符串可分配给{})。


虽然您可以将任何内容分配给类型 {},但无法将 string 分配给 Partial<Car>。对我来说,这似乎更像是一个错误,因为我找不到任何赋值方式使得比较在没有类型断言的情况下评估为 true - Tobias S.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接