【问题标题】:Typescript: incorrect type for object spread operator?打字稿:对象扩展运算符的类型不正确?
【发布时间】:2020-11-23 17:19:55
【问题描述】:

考虑一下这段代码sn-p:

type Foo = {
  x: string;
  y: number;
};

let a: Foo = {
  x: "@",
  y: 3,
};

let b: Partial<Foo> = { x: "#", y: undefined };

let c = { ...a, ...b };

c 的类型显然不能是 Foo,因为属性 yundefinedc 的运行时值是 {x: "#", y: undefined}(至少在 Chrome 中)。然而 Typescript 将 c 类型推断为 { x: string; y: number;}。您可以签入https://www.typescriptlang.org/play 以获取版本 4.0.5。我很困惑。

编辑:这是从 cmets 到 github 问题的链接,问题完全相同 https://github.com/microsoft/TypeScript/issues/13195#issuecomment-373178677 。现在这就是答案。

【问题讨论】:

  • 请看这里github.com/microsoft/TypeScript/issues/13195 另外,AFAIK,传播运算符在 TS 中的输入不是很好
  • TS 和 JS 一样:如果你明确指出一个 prop,它肯定存在于一个对象中,即使是 undefined 值。确保您需要致电hasOwnProperty
  • @captain-yossarian 你应该回答这个问题(也许引用this comment);编译器无法始终理解“present-but-undefined”和“missing”之间的区别。扩展运算符似乎假定缺少 undefined 可选属性,并且不会覆盖以前设置的属性。这个假设在大多数情况下可能是正确的,但在此处的示例中并不正确。请注意,您使用的是必需属性,而不是可选属性,the issue goes away
  • @jcalz 我无法回答,因为我是从您的回答和 cmets 中学到的。你的回答会比我的好)

标签: typescript


【解决方案1】:

主要问题是Partial&lt;Foo&gt;类型:

let b: Partial<Foo> = { x: "#", y: undefined };

当你指定变量类型时,ts编译器通常会忽略赋值的右边,不使用它进行类型推断(有一些例外,但一般都是这样工作的)。

【讨论】:

  • 看不出有什么问题。 { x: "#", y: undefined } 是由类型 Partial&lt;Foo&gt; 定义的集合的有效值。所以TS没有抱怨是对的。相反,如果我写let b: Foo = { x: "#", y: undefined };,TS 理所当然地不高兴
  • 只是为了澄清:“ts 编译器通常会忽略右侧”意味着表达式类型不用于类型缩小,例如声明后变量的有效类型仍然是Partial&lt;Foo&gt;,而不是{x: string; y: undefined}。编译器还有一个问题,它不会为结果传播类型生成可选标志,但我认为这是一个编译器错误
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-22
  • 1970-01-01
  • 2021-01-29
  • 2020-05-28
  • 2018-07-25
  • 1970-01-01
相关资源
最近更新 更多