typescriptstrictnullchecks

Typescript strictNullChecks does not narrow type


I have a simple case when strictNullChecks does not narrow type even though I explicitly check for undefined.

interface WideType {
  one: { two: number } | undefined;
}
interface NarrowType {
  one: { two: number };
}

const example = (value: WideType): NarrowType | null => {
  if (value.one) {
    return value; // I have an error here
  }
  return null;
};

The error message is:

Type 'WideType' is not assignable to type 'NarrowType'.
  Types of property 'one' are incompatible.
    Type '{ two: number; } | undefined' is not assignable to type '{ two: number; }'.
      Type 'undefined' is not assignable to type '{ two: number; }'.ts(2322)

How do I help TS compiler to figure that out? TS version 3.7.2


Solution

  • In order to properly narrow the type you can create custom type guard in a form:

    const isNarrow = (a: WideType): a is NarrowType => !!a.one;
    

    Using in your example:

    interface WideType {
      one: { two: number } | undefined;
    }
    interface NarrowType {
      one: { two: number };
    }
    
    const isNarrow = (a: WideType): a is NarrowType => !!a.one;
    
    const example = (value: WideType): NarrowType | null => {
      if (isNarrow(value)) {
        return value; // value is NarrowType
      }
      return null;
    };