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функций, но этот логический вывод поддерживается для совместимости.