Skip to content

Typescript doesn't detect correct type in constant array. #13578

Closed

Description

TypeScript Version: 2.1.1 / nightly (2.2.0-dev.201xxxxx)

Code

let map = {};

[
    ['foo', false],
    ['bar', true],
    ['baz', true],
].forEach(entry => {
    let id = map[entry[0]];
    let booleanVar = entry[1];
});

Expected behavior:

Typescript could detect that entry[0] is a string so a cast isn't needed.

Actual behavior:

Type 'true' cannot be used as an index type.

The problem is solved using a cast to string, or alternatively (in this case more elegantly) using a map.

Feel free to mark as wontfix or duplicate as appropriate.

Thanks!

Activity

  1. RyanCavanaugh commented on Jan 19, 2017

    @RyanCavanaugh
    Member

    The problem is that we really have no idea that your array isn't mutated. Heterogeneous arrays are sometimes tuples and sometimes just arrays. In this case since you are using an array as a tuple (thus hopefully not calling sort / push / pop on it), you can add a type assertion to inform the checker:

    ([
        ['foo', false],
        ['bar', true],
        ['baz', true],
    ] as ([string, boolean][])).forEach(entry => {
        let id = map[entry[0]];
        let booleanVar = entry[1];
    });
  2. emilio commented on Jan 19, 2017

    @emilio
    Author

    Well, it's a temporary, so I expected Typescript to be able to auto-treat it as constant.

    I guess you could whitelist forEach (and some other methods) as a const method or something, so you know it can't be mutated, but yeah, seems complex enough.

    Thanks for the reply! :)

  3. RyanCavanaugh commented on Jan 19, 2017

    @RyanCavanaugh
    Member

    Not that it particularly matters (since we don't do it either way), but it's the possible mutation of entry that's the issue, which is definitely available to mutate. And forEach on a temporary still isn't guaranteed to be immutable because the array itself is the third argument to the forEach callback (JS: always out to get you).

  4. emilio commented on Jan 19, 2017

    @emilio
    Author

    Oh, of course, sorry :)

  5. locked and limited conversation to collaborators on Jun 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    SuggestionAn idea for TypeScriptToo ComplexAn issue which adding support for may be too complex for the value it adds

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions