Typescript strictNullChecks和数组

时间:2017-07-08 12:41:01

标签: typescript definitelytyped

我没有完全理解Typescript在启用编译器选项strictNullChecks时的行为。似乎有时Typescript(版本2.4.1)理解string[]中的项目是string,有时它不会:

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-07-14更新:

只有在使用downlevelIteration时才会发现这种奇怪的行为。我的tsconfig.json

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

1 个答案:

答案 0 :(得分:0)

经过进一步调查,我可以确认这不是打字稿问题。问题的根源是用于IteratorResult<T>的类型。我使用过@types/core-js 0.9.36

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

value是可选的,这在技术上是正确的,因为根据the iterator protocolvalue&#34;当完成为真时可以省略。&#34;正如我的问题所证明的那样,选择性在实践中没有用。

Typescript附带的类型(&#34; es2015&#34;在tsconfig.json的&#34; lib&#34;部分中配置,即文件lib.es2015.iterable.d.ts)采取更实用的方法,显然假设valuedone时不会使用true

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

为了解决问题,您可以编辑@types/core-js或将其替换为Typescript附带的库。但是,替换不是100%等效 - 请查看this issue进行讨论。