Разбор типа Never в Typescript

Тип never в Typescript

Типизация — это то, почему многие выбирают писать на 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

Об авторе

Антон Ларичев Технический директор и профессиональный разработчик

Работаю техническим директором в компании по продаже и оценке автомобилей с пробегом. Занимают разработкой уже более 12 лет и имею большой опыт: JavaScript, TypeScript, Php, Go, C#, Swift и Python. Активно внедряю гибкие методологии разработки в компании и внутренние обучения для команд.

Мой сайт: https://purpleschool.ru/

На сайте вы можете найти полезные материалы и мои авторские курсы по NodeJS, NextJS, React, Docker, Ansible и другим технологиям.

--

--

--

IT Director in car selling company. In love with TypeScript, NodeJS and Angular.

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Anton Larichev

Anton Larichev

IT Director in car selling company. In love with TypeScript, NodeJS and Angular.

More from Medium

Bundling a TypeScript library for Node with Rollup.JS

JBook, CellList and custom hooks

Implementing Webpack’s Module federation in a Vue 2 application.

render server-side for specific viewports with option to cache with NextJS