Never¶
Youtube: Видеоурок о типе never
Egghead: Видеоурок о типе never
При разработке языка программирования используется понятие bottom типа, который является естественным результатом анализа потока кода. TypeScript выполняет анализ потока кода (😎), поэтому он должен достоверно представлять то, что никогда не произойдёт.
Тип never
используется в TypeScript для обозначения этого типа bottom. Случаи, когда это происходит естественным путем:
- Функция никогда ничего не вернёт (например, если в теле функции есть
while(true){}
) - Функция всегда выбрасывает ошибку (например, в
function foo () {throw new Error ('Не реализована')}
тип возвращаемого значения функцииfoo
-never
)
Конечно, вы можете использовать это описание и сами:
1 |
|
Тем не менее, never
может быть присвоено только другое never. Например:
1 2 3 4 5 6 7 8 |
|
Отлично. Теперь давайте перейдем к основному варианту использования :)
Пример использования: тщательные проверки¶
Вы можете вызывать функции never в never-обстоятельствах.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
А поскольку never
назначается только другому never
, вы также можете использовать его для тщательных проверок во время компиляции. Это описано в разделе размеченные объединения.
Путаница с void
¶
Как только кто-то говорит вам, что возвращается never
, когда функция никогда не завершается корректно и ничего не будет возвращено, вы интуитивно хотите думать об этом как о void
. Однако void
- это значение. "Never" - ложное утверждение в логике.
Функция, которая ничего не возвращает, возвращает значение void
. Однако функция которая никогда ничего не возвращает (или всегда выбрасывает ошибку), возвращает never
. void
- это то, что может быть присвоено (без strictNullChecking
), но never
никогда не может быть присвоено чему-либо, кроме never
.
Логический вывод типа в функциях, которые никогда ничего не возвращают¶
Для объявлений функций TypeScript по умолчанию подразумевает void
, как показано ниже:
1 2 3 4 5 6 7 8 |
|
Конечно, вы можете исправить это подробным описанием:
1 2 3 |
|
Основная причина - обратная совместимость с реальным кодом JavaScript:
1 2 3 4 5 6 7 8 9 10 |
|
Если Base.overrideMe
.
Реальный TypeScript может преодолеть это с помощью
abstract
функций, но этот логический вывод поддерживается для совместимости.