为什么要使用TypeScript';s型防护装置在父范围内的工作方式是否不同?
我有以下代码:为什么要使用TypeScript';s型防护装置在父范围内的工作方式是否不同?,typescript,Typescript,我有以下代码: 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 r
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块内的两行中具有不同的类型。为什么?好问题。这里的根本原因是TypeScript不知道回调是立即调用的,因此保守地认为函数可能在其他赋值之后被调用 考虑以下代码:
let x: string | number = "hello world";
foo(() => console.log(x.substr(2)));
x = 42;
这段代码是崩溃了,还是成功了?没办法知道。这取决于foo
是立即执行其回调,还是稍后执行(例如foo
是window.setTimeout
)。它甚至可以两者兼得
请注意,如果您说的是const
而不是let
,TypeScript可以知道变量“以后”不会更改类型:
真有趣!我想知道这个类型的守卫是否延伸到了那个街区内的lambdas。谢谢!这确实解释了乍一看这种奇怪的行为,现在完全有道理了。
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
}