Typescript strictNullChecks не сужает тип

У меня простой случай, когда strictNullChecks не сужает тип, хотя я явно проверяю 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;
};

Сообщение об ошибке:

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)

Как я могу помочь компилятору TS разобраться в этом? TS версии 3.7.2

2 ответа

Решение

Чтобы правильно сузить тип, вы можете создать собственный тип защиты в форме:

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

Используя в вашем примере:

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;
};

Защита типа работает только с типом, а не с свойством, что означает:

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

const example = (value: WideType): NarrowType | null => {
  if (value.one) {
    // return value; // You have an error here, as value.one is not undefined, but value is still a WideType
    return {one: value.one}; // This works as value.one is not undefined
  }
  return null;
};
Другие вопросы по тегам