Typescript: Expressions in typeof undefined checks should not error on undefined

Created on 4 Oct 2017  路  6Comments  路  Source: microsoft/TypeScript

I think typeof undefined checks should not error in the last accessor of the expression. Because I'm already checking for undefined:

So below code should be perfectly fine:

interface A {
    a: string;
}

interface B {
    b: string;
}

function isA(x: A |聽B): x is A {
    return typeof x.a !== 'undefined'; // Error in "a" does not exists
}

Right now, I have to type assert x to any.

Design Limitation

All 6 comments

(You forgot to quote undefined, right now that check is _always_ false)

This is a consequence of | types only allowing access to the subset of common known keys, because something that matches A is also allowed to coincidentally have a key that would have matched B, and vice-versa.

If you add b: never to A and a: never to B, this will allow you to test them for refinement even without needing an assertion function.

This is a suggestion to allow non-existing accessors to be allowed just in typeof undefined checks.

Without exact types (#12936) this is unsound.

interface A {
    a: string;
}

interface B {
    b: string;
}

function isA(x: A | B): x is A {
    return typeof (x as any).a !== 'undefined';
}

function f(value: A | B): string {
    return isA(value) ? value.a.toUpperCase() : value.b.toLowerCase();
}

// Crashes on `1.toUpperCase()`
console.log(f({ a: 1, b: "" }));

Even though it is unsound, my suggestion is still to allow one to write:

typeof x.a !== 'undefined';

Instead of having to:

typeof (x as any).a !== 'undefined';

And this should only work on typeof undefined checks. Because you are checking undefined on runtime and the compiler shouldn't complain about a non-existent property.

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

Was this page helpful?
0 / 5 - 0 ratings