2017-07-08 69 views
3

我沒有完全理解Typescript的行爲,並且啓用了編譯器選項strictNullChecks。看來,有時打字稿(版本2.4.1)瞭解到,在string[]的項目是string,有時則沒有:Typescript strictNullChecks和數組

interface MyMap { 
    [key: string]: string[]; 
} 

function f(myMap: MyMap) { 
    const keys = Object.keys(myMap); // keys: string[] => Fine. 
    for (let key of keys) { // key: string | undefined => Why? 
     key = key as string // So a cast is needed. 
     const strings = myMap[key]; // strings: string[] => Fine. 
     const s = strings[0]; // s: string => Fine. 

     // Error: 
     // Argument of type 'string | undefined' is not assignable to parameter of type 'string'. 
     // Type 'undefined' is not assignable to type 'string'. 
     useVarArgs(...strings); 
    } 
} 
function useVarArgs(...strings: string[]) { 
} 

更新2017年7月14日:

這種奇怪的行爲是僅在使用downlevelIteration時才被觀察到。我的tsconfig.json

{ 
    "compilerOptions": { 
    "target": "es5", 
    "outDir": "target", 
    "downlevelIteration": true, 
    "strictNullChecks": true 
    } 
} 
+3

您使用的是什麼版本的TypeScript?你的代碼看起來很好[TypeScript Playground](http://www.typescriptlang.org/play)。 – Saravana

+0

對不起,我忘了提。版本2.4.1。還編輯了問題。 –

+1

我在2.4.1上測試了你的代碼,它工作正常。 'key'是需要投射的字符串,並且沒有你提到的問題。 – unional

回答

0

經過進一步調查,我可以確認這不是一個Typescript問題。問題的根源是用於IteratorResult<T>的類型。我用了@types/core-js 0.9.36

interface IteratorResult<T> { 
    done: boolean; 
    value?: T; 
} 

value是可選的,這在技術上是正確的,因爲根據the iterator protocolvalue「可以做到,如果省略,真的。」正如我的問題所證明的那樣,選擇性在實踐中並不有用。

隨打字稿(「ES2015」爲配置了「LIB」部分中在tsconfig.json,即文件lib.es2015.iterable.d.ts)類型採取更爲實際的方法,顯然假設value將不被使用時donetrue

interface IteratorResult<T> { 
    done: boolean; 
    value: T; 
} 

爲了解決該問題,您可以編輯@types/core-js或將其替換爲隨Typescript附帶的庫。更換不是100%等效,但請參閱this issue進行討論。