我有这段代码:
function isNumberArray(l: any[]): l is number[] {
let res = true;
for (let e of l) {
res = res && (typeof e === 'number');
}
return res;
}
let arr:(number|string)[] = [1, 2];
if (isNumberArray(arr)) {
let res1: number = arr[1]; //OK
let res2: number = [1].map(i => arr[i])[0]; // ERROR: Type 'string | number' is not assignable to type 'number'
}
由于某种原因,变量arr在if块内的两行中有不同的类型。为什么呢?
答案 0 :(得分:2)
好问题。这里的根本原因是TypeScript不知道立即调用回调,因此做出保守的假设,即可能在其他赋值发生之后调用该函数。
考虑一下这样的代码:
let x: string | number = "hello world";
foo(() => console.log(x.substr(2)));
x = 42;
此代码崩溃或成功吗?没有办法知道。这取决于foo
是立即执行其回调还是稍后(例如foo
是window.setTimeout
)。它甚至可以做到这两点!
请注意,如果您说过const
而不是let
,那么TypeScript可以知道该变量“不会在以后”更改类型:
const arr:(number|string)[] = [1, 2];
if (isNumberArray(arr)) {
let res1: number = arr[1]; //OK
let res2: number = [1].map(i => arr[i])[0]; // OK
}