Пейджер

Интересный факт, который я узнал. Оказывается, помимо обычных type guard'ов, есть

TL;DR
  • Type guards сужают тип через `value is Type`, возвращая boolean
  • Assertion functions используют `asserts value is Type` и бросают ошибку
  • Вариант `asserts value` без типа проверяет на falsy
Интересный факт, который я узнал. Оказывается, помимо обычных type guard'ов, есть

Assertion Functions

Для начала для тех, кто не в курсе, type guards — это механизм TS, который позволяет создать метод, результат выполнения которого будет сужать тип переданной переменной. Для этого нужно в аннотации возвращаемого значения метода через ключевое слово is указать, какая переменная к какому типу приводится, а из функции вернуть boolean, который указывает на принадлежность к целевому типу. Самый простой и банальный пример:
const isString = (value: unknown): value is string => typeof value === 'string';

let someValue!: string | number;

if (isString(someValue)) {
  someValue.toUpperCase(); // OK
} else {
  someValue.toFixed(2); // OK
}


Или другой пример — разобранный ранее доопределенный Array.includes

Assertion functions работают также, только функция должна быть объявлена через function (см. дополнение ниже) и вместо того, чтобы возвращать boolean, функция бросает ошибку при несоответствии переменной типу, и в предикате добавляется ключевое слово asserts:
function assertiveIsString(value: unknown): asserts value is string {
  if (typeof value !== 'string') {
    throw new Error('value is not a string');
  }
}

let someValue!: string | number;

try {
  assertiveIsString(someValue);

  someValue.toUpperCase(); // OK
} catch (error) {}

Помимо этого, можно указать только ключевое слово asserts и переменную, в таком случае будет проверка на то, что значение не falsy:
function notFalsy(value: unknown): asserts value {
  if (!value) throw new Error();
}

let falsy!: '' | false | undefined | null | 0;

try {
  notFalsy(falsy);

  const never: never = falsy; // OK
} catch (e) {}


Сам с ситуаций, где бы мне нужно было сужать тип в таком формате, не встречался, да и в целом он мне кажется несколько странным, но возможно кому-то этого не хватало

Тут разобранные примеры
Хотите больше таких постов?
Подпишитесь на канал и читайте продолжение в Telegram.
Подписаться на @typescript_bowl Открыть пост в Telegram