Typescript strictNullChecks and arrays

I don't quite understand the behavior of Typescript with the compiler option enabled strictNullChecks

. It seems that sometimes Typescript (version 2.4.1) understands that the element in string[]

is string

, and sometimes it is not:

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[]) {
}

      

Update 2017-07-14:

This strange behavior is only seen in use downlevelIteration

. My tsconfig.json

:

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

      

+3


source to share


1 answer


After further research, I can confirm that this is not a Typescript issue. The source of the problem is the types used for IteratorResult<T>

. I used @types/core-js 0.9.36

:

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

      

value

is optional, which is technically correct because according to the iterator protocol , value

"May be omitted when done right." As my question has shown, optional is not practical in practice.



The types supplied with Typescript ("es2015" as stated in the "lib" section in the tsconfig.json

ie file lib.es2015.iterable.d.ts

) take a more pragmatic approach, obviously assuming that value

it won't be used if done

- true

:

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

      

To fix this problem, you can either edit @types/core-js

or replace it with libraries loaded with Typescript. Replacement is not 100% equivalent - see this issue for a discussion.

0


source







All Articles