typescript

TypeScript failing to infer type is not undefined after type guard with logical or


In the code below, in the else block, it is clear that b cannot be undefined (a||b is truthy and a is falsy so b must be truthy).

Why does Typescript produce the error 'b' is possibly 'undefined', and how can I avoid this error?

function test(a: string | undefined, b: string | undefined) {
  if (a || b) {
    if (a) {
      const x = a.length
    } else {
      const y = b.length
    }
  }
}

Solution

  • You can debug it like this:

    function test(a: string | undefined, b: string | undefined) {
      type A1 = typeof a; // string | undefined
      type B1 = typeof b; // string | undefined
      if (a || b) {
        type A2 = typeof a; // string | undefined
        type B2 = typeof b; // string | undefined
        if (a) {
          type A3 = typeof a; // string
          type B3 = typeof b; // string | undefined
          const x = a.length
        } else {
          type A4 = typeof a; // string | undefined
          type B4 = typeof b; // string | undefined
          const y = b.length
        }
      }
    }
    

    Basically, (a || b) is not able to narrow down the types.

    The conditional flow analysis look for !== undefined and !== null checks (this is a known limitation of TS), you should re-write it as follows:

    function test(a: string | undefined, b: string | undefined) {
      if (a !== undefined ) {
        const x = a.length; // number
      } else if(b !== undefined){
        const y = b.length; // number
      }
    }