Enums
полезно использовать когда мы хотим ограничить область значений той или иной переменной. По аналогии с литеральными типами
мы можем задать набор значений, которые будет принимать в себя переменная с данным типом enum
. Это удобнее обычных литеральных типов.
enum Direction {
Up, // автоматически тип Up будет 0
Down, // Down тип 1
Left, // тип 2
Right // тип 3
}
Это числовое предаставление enums
, по умолчанию они называются числовые enums
.
Мы так же можем сами установить последовательность.
enum Direction {
Up = 1, // меняем на 1
Down, // Down тип 2
Left, // тип 3
Right // тип 4
}
Со строковыми enums
нам нужно будет каждому установить свое результирующее значение.
enum Direction {
Up = 'Up',
Down = 'Down',
Left = 'Left',
Right = 'Right'
}
Это просто смесь строковых значений и числовых.
enum Desicion {
Yes = 1,
No = 'No'
}
Мы можем рассчитать значение в enum
.
enum Desicion {
Yes = 1,
No = calcEnum() // вызываем нашу функцию расчета
}
function calcEnum () { // создаем функцию которая расчитывает
return 0;
}
Такой вариант может осуществляться только с числовым типом.
enum Test {
A
}
let test = Test.A; // поместили в test значение A
console.log(test); // A по умолчанию 0
// что бы получить само имя, можно сделать так.
let nameA = Test[test]; // мы как бы по индексу получили имя.
console.log(nameA); // A
Если мы собираемся использовать enum
как константу, то можно объявлять такой enum
через const
enum Test {
A
}
let oneEnum = Test.A;
Выше мы объявили просто enum
, давайте скомпилируем его и посмотрим, что будет в js
файле:
// А тут мрак функциональный
var Test;
(function (Test) {
Test[Test["A"] = 0] = "A";
})(Test || (Test = {}));
let oneEnum = Test.A;
Теперь посмотрим на const enum
const enum Test2 {
B
}
let twoEnum = Test2.B;
Скомпилируем:
let twoEnum = 0 /* B */;
Намного легче и проще читается, да? Поэтому если enum
используется только как константа то лучше использовать const enum
never
- это примитивный тип данных, ложное логическое утверждение.Служит для указания того, что какие-либо операции никогда не будут выполнены.
Мы знаем, что функция которая ничего не возвращает, возвращает void
, однако, если функция выбрасывает ошибку, то она будет возвращать never
.
never
можно указать, функции либо с ошибкой, либо если она никогда не сможет выполнить что либо, например бесконечный цикл.
function hi ():never {
hi()
}
Если же убрать бесконечную рекурсию, то мы получим ошибку, так как это уже функция которая ничего не возвращает, а значит ее тип будет void
.
function hi ():void {
}
Или ошибка:
function error(message: string): never {
throw new Error(message);
}
То есть это все то, что не должно выполниться.
Где это можно использовать? например с enum
или type
.
type AdminAction = 'CREATE' | 'ACTIVATE'; // если тут добавить еще значение, то будет ошибка
function doAction (action:AdminAction) {
switch(action) {
case 'CREATE':
return "CREATED"
case 'ACTIVATE':
return 'ACTIVATED'
default:
const a: never = action; // вот тут будет ошибка
throw new Error (`НЕ ПОНЯЛ ЧТО ТУТ ${a}`)
}
}
Это нам помогает заметить ошибку, если мы в type
добавим третье значение и уберем never
, то ничего не будет подсвеченно.
Тот же пример с enum
enum AdminAction {
CREATE = "CREATE",
ACTIVATE = "ACTIVATE",
};
function doAction(action: AdminAction) {
switch (action) {
case AdminAction.CREATE:
return "CREATED"
case AdminAction.ACTIVATE:
return 'ACTIVATED'
default:
const a: never = action;
throw new Error(`НЕ ПОНЯЛ ЧТО ТУТ ${a}`)
}
}