typescript - 为什么将变量重新分配给新对象时类型推断不适用于对象属性?

标签 typescript

为什么将变量重新分配给新对象时类型推断不适用于对象属性?

示例(TypeScript v3.4.5):

// compiles
let myVar: string | number;
myVar = '5';
console.log(myVar.length);

// compiles
let myObj1: {myProp: string | number} = {myProp: 5};
myObj1.myProp = '5';
console.log(myObj1.myProp.length);

// does not compile, emitting the following error:
// TSError: ⨯ Unable to compile TypeScript:
// myt.ts(63,26): error TS2339: Property 'length' does not exist on type 'string | number'.
//   Property 'length' does not exist on type 'number'.
let myObj2: {myProp: string | number} = {myProp: 5};
myObj2 = {myProp: '5'};
console.log(myObj2.myProp.length);

最佳答案

我认为这里发生的事情是 narrowing upon assignment 的规则仅适用于 union types 的值,无论好坏:

An assignment (including an initializer in a declaration) of a value of type S to a variable of type T changes the type of that variable to T narrowed by S in the code path that follows the assignment.

[snip]

The type T narrowed by S is computed as follows:

  • If T is not a union type, the result is T.
  • If T is a union type, the result is the union of each constituent type in T to which S is assignable.

已经suggested to lift this restriction ,但现在就是这样。
还要注意类型A | B是联合,而类型 {x: A | B}不是。是的,{x: A | B}有一个类型是联合类型的属性,但它本身不是联合类型。

那么让我们看看这里发生了什么:
let myObj1: { myProp: string | number } = { myProp: 5 };
好的,这是分配一个非联合类型的值。所以我们可以预期这里不会缩小。让我们确保:
myObj1.myProp.toFixed(); // error!
是的,没有发生缩小。继续:
myObj1.myProp = "5";
好的,这是分配类型 string | number 的值,联合类型。所以我们可以预期这里会缩小。让我们确保:
console.log(myObj1.myProp.length); // no error
是的,缩小。然后剩下的:
let myObj2: { myProp: string | number } = { myProp: 5 };
myObj2 = { myProp: "5" };
这些都是分配非联合类型的值......所以,没有缩小:
myObj2.myProp.length; // error!
是的,没有缩小。

所以这可能是为什么会发生这种情况的规范解释。至于所有作业是否都应该缩小范围……如果您觉得应该缩小范围,您可能需要访问 relevant Github issue, microsoft/TypeScript#27706如果您认为它特别引人注目,请给它一个 👍 或描述您的用例。
好的,希望有帮助;祝你好运!
Link to code

关于typescript - 为什么将变量重新分配给新对象时类型推断不适用于对象属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58262028/

相关文章:

reactjs - 如何从 Sharepoint 在线 SPFx Web 部件使用 Azure 认知搜索

javascript - Javascript/Typescript 中对象数组的数据集

Angular 6 : Reactive Form's updateOn: 'submit' is not updating value after submitting

javascript - 我应该将 props 作为参数传递给组件内的函数吗?

reactjs - 如何使用 Ionic、React、Yup 和 Resolvers 解决“.”上的 "termsOfUse must be a boolean type, but the final value was: "

javascript - Angular/Typescript——通过示例解释接口(interface)的好处

jquery - 导入 jquery 后,Typescript 找不到名称 '$'?

javascript - Kendo、TypeScript 定义错误 :

javascript - ReactJS:渲染组件时触发方法

typescript - 在 typescript 中定义 lambda 函数的问题