Lars Nyström
Lars Nyström

Reputation: 6393

Why doesn't this type guard work in this ternary expression?

I have this code:

function isArray(v: any): v is any[] {
    return Array.isArray(v);
}

type Settings = {
    [key: string]: string | string[]
}

function myfunc(settings: Settings) {
    Object.keys(settings).forEach(key => (
        (isArray(settings[key]))
            ? settings[key].forEach(val => console.log(val))
            : console.log(settings[key])
    ));
}

Playground link

At settings[key].forEach( I'm seeing the message:

Property 'forEach' does not exist on type 'string | string[]'.
Property 'forEach' does not exist on type 'string'.

So why doesn't the isArray type guard work?

Upvotes: 2

Views: 1565

Answers (1)

georg
georg

Reputation: 215029

Type guards don't work with getter expressions, like here

    (isArray(settings[key]))  // (1)
        ? settings[key].forEach(val => console.log(val)) // (2)

because the compiler cannot be sure that settings[key] in (1) and (2) are the same thing. You have to assign it to a temp variable first:

    let temp = settings[key];
    (isArray(temp))
        ? temp.forEach(val => console.log(val))
        : console.log(temp)

Upvotes: 5

Related Questions