Search code examples
typescriptstricttype-deduction

How to quickly discriminate between interfaces with non-overlapping properties


In typescript, I commonly have a variable with a type like:

const variable: { a: string } | { b: number };

When I want to check what shape the variable has, I usually want to do

if (variable.a !== undefined) {
  // do stuff
}
else {
  // do stuff

However in strict mode, typescript throws a type error at variable.a because variable is not known to have the property a. To get around this, I usually cast to any like (variable as any).a !== undefined. However typescript doesn't treat this as a type guard and doesn't narrow the type of variable.

Is there a "proper" way of doing this check in typescript when in strict mode (without making a custom type guard)?

Some examples I've tried (which, unfortunately, also throw type errors):

  • typeof variable.a !== 'undefined'
  • variable.hasOwnProperty('a')

Solution

  • The simplest way to discriminate in this case would be an in type guard:

    declare const variable: { a: string } | { b: number };
    
    
    if ('a' in variable) {
        variable.a
    }
    else {
        variable.b
    }