为什么将变量重新分配给新对象时类型推断不适用于对象属性?
示例(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 typeT
changes the type of that variable toT
narrowed byS
in the code path that follows the assignment.[snip]
The type
T
narrowed byS
is computed as follows:
- If
T
is not a union type, the result isT
.- If
T
is a union type, the result is the union of each constituent type inT
to whichS
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/