为什么分配给先前键入的变量会更改其类型?

时间:2019-02-11 22:00:16

标签: typescript

下面的第3行显示foo的类型为"a"|"b",在第7行,我们可以将foo"b"进行比较:

1 let foo: "a"|"b";
2 
3 // error: Type '"c"' is not assignable to type '"a" | "b"'.
4 foo = "c";
5 
6 switch (foo) {
7     case "b": break; // legal comparison
8 }

这正是我所期望的。

但是,如果我将值“ a”分配给foo,则会更改foo 的类型,因此与"b"的比较不会有效期更长:

1 let foo: "a"|"b";
2 
3 // this line changes the type of foo to '"a"', rather than '"a"|"b"'
4 foo = "a";
5 
6 switch (foo) {
7     // error: Type '"b"' is not comparable to type '"a"'
8     case "b": break; // illegal comparison!
9 }

这到底是怎么回事?为什么为强类型变量分配合法值会更改变量的类型?

2 个答案:

答案 0 :(得分:2)

正如其他人所说,TypeScript根据使用情况推断类型。还值得注意的是,它仅对联合类型(即Type1 | Type2

)执行此操作

您可以将推断类型视为“时间点”类型。

let foo: "a"|"b";
foo = 'a'; // foo has inferred type 'a' but actual type is still 'a'|'b'
foo = 'b'; // We can still assign 'b', foo now has inferred type 'b'

在您的示例中,您得到了:

// error: Type '"b"' is not comparable to type '"a"'

这是因为在此时,TypeScript 知道 foo的类型为'a',而不是'b',因此它更新了你。

另一个示例是当您在完全不同的类型之间创建联合时:

let foo: string | number;
let bar: any = 'b';

foo = bar; // foo is now 'b' but has type string | number

foo.charAt(0); // Error: Property 'charAt' does not exist on type 'string | number' 

foo = 'a'; // foo now has inferred type of string

foo.charAt(0); // Can use string functions

foo = 24.123; // inferred type of number

foo.toFixed(0);

通过缩小/推断类型,我们现在可以使用仅在联合类型之一上可用的属性。

答案 1 :(得分:1)

Typescript根据用法推断类型,在这里进行描述:https://www.typescriptlang.org/docs/handbook/type-inference.html

因此,在您使用Typescript的上下文类型算法时,直到您分配值之前,它一直使用通用类型。