2016-09-26 2 views
4

私はこのコードを持っている:何らかの理由で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 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ブロック内の2行の異なる種類があります。どうして?

+0

面白いです!タイプガードがそのブロックの中のラムダに及ばないのだろうかと思う。 – Paarth

答えて

2

大きな質問です。ここでの根本的な原因は、コールバックが直ちに呼び出されることをTypeScriptが認識しないため、他の代入が発生した後に関数が呼び出される可能性があるという控えめな仮定になります。

は、このようないくつかのコードを考えてみましょう:

let x: string | number = "hello world"; 
foo(() => console.log(x.substr(2))); 
x = 42; 

は、このコードのクラッシュをい、または成功しますか?知る方法はありません。 fooがすぐにコールバックを実行するかどうかによって異なります(たとえばfoowindow.setTimeout)。それは両方を行うこともできます!あなたがconst代わりのletを言っていた場合、活字体は「後で」変数が種類を変更していないことを知ることができることを

注:

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 
} 
+0

ありがとうございました!これは、一見したところでは今、完全に意味をなさない奇妙な行動でこれを実際に説明します。 –

関連する問題