How to reassign an object with a type narrowed prop in typescript?

183 views Asked by At

Object properties can be type-narrowed by conditionals, but reassigning the whole object to another variable causes an error. Is there any workaround?

type A = {
  prop: string | number;
}
type B = {
  prop: string;
}

function f(a: A) {
  if (typeof a.prop === 'string') {
    let str: string = a.prop; // No error
    let b: B = a; // Error
  }
}
2

There are 2 answers

0
Mads K On

With TypeScript, the exact type information (defined via TypeScript) is not available at runtime. In other words, the typeof operator doesn't necessarily work as you intend in this case, as it does not return TypeScript's type information, but instead the JavaScript type/primitive (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof). In other words, you need to use a different method to guarantee that the type is indeed correct.

As I see it, in this case you could either use a discriminator value (a property which will tell you via a constant value which type you are dealing with), actual TypeScript classes, or alternatively use a type guard, as in Tobias' solution.

0
Tobias S. On

You may solve this with a type guard:

function AisB(a: A): a is B {
  return typeof a.prop === "string"
}

function f(a: A) {
  if (AisB(a)) {
    let str: string = a.prop; // No error
    let b: B = a; // No error
  }
}