typescripttypeguards

How to check if property exists if obj is one of types


Let's say I have few interfaces A, B, C implementing common Base.

interface Base {
    x: number;
    y: number;
    z: number;
}

interface A extends Base {
    a: true;
}

interface B extends Base {
    b: true;
}

interface C extends Base {
    C: true;
}

And function with if statements:

function foo(arg: A|B|C){
    if(arg.a!==undefined){//throws type error
        //do stuff for type a
    } else if(arg.b !== undefined){//throws type error
        //do stuff for type b
    } else if(arg.c !== undefined){ //throws type error
        //do stuff for type c
    }
}

How to correctly check if property exists? I don't wan't to use any type. Is //@ts-ignore only option?


Solution

  • You can use a type guard:

    function isA(arg: A | B | C): arg is A {
        return (<A>arg).a !== undefined;
    }
    
    function isB(arg: A | B | C): arg is B {
        return (<B>arg).b !== undefined;
    }
    
    function foo(arg: A | B | C) {
        if (isA(arg)) {
            // do stuff for type a
        } else if (isB(arg)) {
            // do stuff for type b
        } else {
            // do stuff for type c
        }
    }