Антон Ларичев
Типизация - это то, почему многие выбирают писать на TypeScript, а не на чистом JavaScript. Хотя на конференциях можно услышать доклады "Почему вам не нужен TS", в больших проектах без него просто не обойтись. А если писать на нём регулярно, то уже даже в небольших проектах обычный JS будет приносить только боль. Я это ощутил, при подготовке уроков по NodeJS для следующего курса, где не используется TypeScript.
Потому важно понимать все особенности типизации. Разберём тип never, который многим, кто знакомится с TypeScript непонятен.
Не путать с void!
Тип void в возвращаемом типе функции, обозначает что функция ничего не возвращает (или по иному говоря возвращает undefined).
const a = (): void => {
return undefined;
}В свою очередь переменной типа never можно присвоить только тип never и никакой другой. Кажется бесполезным? Рассмотрим 3 примера использования:
Исчерпывающие проверки типов
Вот пример функции, которая возвращает тип never:
export const error = (message: string): never => {
throw new Error(message);
}На самом деле любая функция, которая кидает ошибку, возвращает этот тип среди других типов. Это можно использовать для исчерпывающих проверок типов.
export const typeRun = (x: string | number): boolean => {
if (typeof x === 'string') {
return true;
} else if (typeof x === 'number') {
return false;
}
return error("!");
}Если бы не использовали never, TS бы выдавал ошибку, так как мы в теории могли бы попасть дальше проверки и вернуть undefined вместо boolean.
Switch / case
Рассмотрим следующий пример:
export type Direction = 'up' | 'down';
export const run = (direction: Direction) => {
switch (direction) {
case 'up':
return 1;
case 'down':
return -1;
default:
const a: never = direction;
}
}Если у нас в Direction добавится новое направление, скажем right, то TypeScript за счёт типа подскажет, что у нас switch больше не валиден, так как при новом значении Direction мы уже можем попасть в default и у нас типу never будет присвоено значение другого типа, что недопустимо.
Conditional types
Благодаря never мы можем исключить не нужные типы. Например, сделаем тип, который если у нас передано значение с number мы присваиваем never. Тем самым мы оставляем только нужный тип в типе А:
type NonNumber<T> = T extends number ? never : T;
type A = NonNumber<string | number>; // A - всегда string


Комментарии
0