Здесь показаны различия между двумя версиями данной страницы.
| Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия | ||
|
typescript:types:never [2023/01/29 20:36] werwolf |
typescript:types:never [2023/07/26 16:50] (текущий) werwolf |
||
|---|---|---|---|
| Строка 1: | Строка 1: | ||
| - | ====Undefined примитивный неопределенный тип==== | + | Never примитивный тип¶ Примитивный типа данных Never служит для указания того, что какие-либо операции никогда не будут выполнены. |
| - | Примитивный тип undefined указывает на то, что значение не определено. Тип данных undefined указывается с помощью ключевого слова undefined (не путать со свойством глобального объекта undefined, которое представляет единственное значение типа Undefined). | + | |
| - | <code javascript> | + | Never обозначается ключевым словом never и так же, как и void, не имеет явных значений. |
| - | let identifier: undefined = undefined; // undefined, указанный после оператора двоеточия, это имеющийся только в TypeScript псевдоним (alias) для глобального типа Undefined. | + | |
| - | </code> | + | |
| - | В то время как undefined, указанный после оператора присваивания, это единственное значение типа Undefined. | + | Тип данных never является подтипом всех типов, что делает его совместимым со всеми остальными типами. |
| - | Во время выполнения объявленные, но не инициализированные переменные, поля и свойства класса, а также параметры имеют значение undefined. Также значение undefined является результатом вызова методов или функций, которые не возвращают значения. | + | |
| - | Тип undefined является подтипом всех типов, что делает его совместимым со всеми остальными типами. | ||
| <code javascript> | <code javascript> | ||
| + | function action(): never { | ||
| + | throw new Error(); | ||
| + | } | ||
| + | |||
| class TypeSystem { | class TypeSystem { | ||
| - | static any: any = undefined; // Ok | + | static any: any = action(); // Ok |
| - | static number: number = undefined; // Ok | + | static number: number = action(); // Ok |
| - | static string: string = undefined; // Ok | + | static string: string = action(); // Ok |
| - | static boolean: boolean = undefined; // Ok | + | static boolean: boolean = action(); // Ok |
| - | static null: null = undefined; // Ok | + | static null: null = action(); // Ok |
| - | static undefined: undefined = undefined; // Ok | + | static undefined: undefined = action(); // Ok |
| + | static void: void = action(); // Ok | ||
| + | static never: never = action(); // Ok | ||
| } | } | ||
| + | |||
| + | TypeSystem.never = TypeSystem.any; // Error | ||
| + | TypeSystem.never = TypeSystem.number; // Error | ||
| + | TypeSystem.never = TypeSystem.string; // Error | ||
| + | TypeSystem.never = TypeSystem.boolean; // Error | ||
| + | TypeSystem.never = TypeSystem.null; // Error | ||
| + | TypeSystem.never = TypeSystem.undefined; // Error | ||
| + | TypeSystem.never = TypeSystem.void; // Error | ||
| + | TypeSystem.never = TypeSystem.never; // Ok | ||
| </code> | </code> | ||
| - | Может возникнуть вопрос, почему тип null, который не имеет непосредственного отношения к типу undefined, совместим с ним? На данный момент, этот вопрос так и остается неразгаданным. | ||
| - | В то время как тип данных undefined совместим со всеми типами, помимо него самого, с ним совместимы лишь null и any. | + | Так как типу never нельзя присвоить значение, отличное от самого типа never, единственным местом, в котором его может использовать разработчик, является аннотация возвращаемого из функции или метода значения, с одной оговоркой. Тип never можно указать только той функции, из которой программа действительно никогда не сможет выйти. |
| + | |||
| + | Такой сценарий может выражаться в виде функции, вызов которой приведет к однозначному исключению или тело функции будет включать бесконечный цикл. | ||
| <code javascript> | <code javascript> | ||
| - | TypeSystem.undefined = TypeSystem.any; // Ok | + | function error(message: string): never { |
| - | TypeSystem.undefined = TypeSystem.number; // Error | + | throw new Error(message); |
| - | TypeSystem.undefined = TypeSystem.string; // Error | + | } |
| - | TypeSystem.undefined = TypeSystem.boolean; // Error | + | |
| - | TypeSystem.undefined = TypeSystem.null; // Ok | + | function loop(): never { |
| + | while (true) {} | ||
| + | } | ||
| </code> | </code> | ||
| - | Тогда, когда тип данных undefined указывается не явно, компилятор устанавливает тип any. | + | Вывод типов определит принадлежность возвращаемого функцией значения к типу never, только если он указан в аннотации возвращаемого типа явно. |
| - | + | ||
| - | let identifier = undefined; // identifier: any | + | |
| - | При активном флаге --strictNullChecks, тип undefined является подтипом только одного типа any. Поэтому ему в качестве значения, помимо самого себя, можно присвоить только тип any. | + | |
| <code javascript> | <code javascript> | ||
| - | class TypeSystem { | + | function error(message: string): never { |
| - | static any: any = undefined; // Ok | + | throw new Error(message); |
| - | static number: number = undefined; // Error | + | |
| - | static string: string = undefined; // Error | + | |
| - | static boolean: boolean = undefined; // Error | + | |
| - | static null: null = undefined; // Error | + | |
| - | static undefined: undefined = undefined; // Ok | + | |
| } | } | ||
| - | TypeSystem.undefined = TypeSystem.any; // Ok | + | function action() { |
| - | TypeSystem.undefined = TypeSystem.number; // Error | + | // function action(): never |
| - | TypeSystem.undefined = TypeSystem.string; // Error | + | return error('All very, very bad.'); |
| - | TypeSystem.undefined = TypeSystem.boolean; // Error | + | } |
| - | TypeSystem.undefined = TypeSystem.null; // Error | + | |
| + | let identifier = error(); // let identifier: never | ||
| + | let identifier = action(); // let identifier: never | ||
| </code> | </code> | ||
| - | При активном флаге **--strictNullChecks**, при условии, что в качестве значения выступает значение undefined, вывод типов определяет принадлежность к типу undefined. | + | Стоит заметить, что без явного указания типа never вывод типов определит принадлежность возвращаемого значения к типу void. |
| <code javascript> | <code javascript> | ||
| - | let identifier = undefined; // identifier: undefined | + | function error(message: string) { |
| + | // function error(): void | ||
| + | throw new Error(message); | ||
| + | } | ||
| + | |||
| + | function loop() { | ||
| + | // function loop(): void | ||
| + | while (true) {} | ||
| + | } | ||
| </code> | </code> | ||
| - | Тип undefined идентичен по своей работе с одноимённым типом из JavaScript. | + | Тип never является уникальным для TypeScript. В JavaScript подобного типа не существует. |
| + | |||