Это третья статья из серии из трех статей о типах данных, предоставляемых языком программирования TypeScript. Части 1 и 2 находятся здесь и здесь. В этой статье я расскажу о перечислениях, а также о значениях undefined, null, never и void, которые могут вести себя как типы данных.

Перечисления

В большинстве языков программирования перечисления — это средство присвоения идентификаторов целочисленным значениям, что делает целочисленную константу. Вот пример на C++, который должен быть понятен программисту на JavaScript:

enum Day {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY};

Вот эквивалент в TypeScript:

enum Day {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY}

Между этими двумя операторами нет никакой разницы, кроме обязательной точки с запятой в C++.

Каждый идентификатор, указанный внутри фигурных скобок, теперь сопоставляется с целым числом, начиная с 0. Вы также можете сделать это сопоставление явным, объявив перечисление следующим образом:

enum Day {MONDAY=0, TUESDAY=1, WEDNESDAY=2, THURSDAY=3,
          FRIDAY

Если вы не хотите начинать с 0, вы можете начать с любого числа и позволить системе закончить нумерацию, как в этом примере:

enum Day {MONDAY=1, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY}

Идентификатору TUESDAY теперь присваивается значение 2, WEDNESDAY — 3 и так далее.

После того как вы объявили перечисление, вы можете объявить переменную типа перечисления. Например:

let workday = Day.MONDAY

Вы также можете создать массив перечислений:

enum Day {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY,
          SATURDAY, SUNDAY}
let workDays :Day = []
workDays.push(Day.MONDAY)
workDays.push(Day.TUESDAY)
workDays.push(Day.WEDNESDAY)
workDays.push(Day.THURSDAY)
workDays.push(Day.FRIDAY)

Как я уже упоминал, перечисляемая переменная хранит целочисленное значение. Этот пример демонстрирует этот факт:

enum Day {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY,
          SATURDAY, SUNDAY}
let workDays :Day = []
workDays.push(Day.MONDAY)
workDays.push(Day.TUESDAY)
workDays.push(Day.WEDNESDAY)
workDays.push(Day.THURSDAY)
workDays.push(Day.FRIDAY)
for (let aDay of wordDays) {
  console.log(aDay)
}

Эта программа отображает:

0
1
2
3
4

Перечисления полезны, когда используются в сочетании с необходимостью сделать выбор, который можно свести к целочисленному результату. Мой любимый пример — использование перечисления в сочетании с оператором switch, как показано в этом фрагменте кода:

enum Day {MONDAY=1, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY,
          SATURDAY, SUNDAY}
let dayOfWeek = Day.WEDNESDAY
switch(dayOfWeek) {
  case Day.MONDAY:
    console.log("Meeting day")
    break
  case Day.TUESDAY
    console.log("Work in cubicle day")
    break
  case Day.WEDNESDAY
    console.log("In the field day")
    break
  case Day.THURSDAY
    console.log("Work in cubicle day")
    break
  case Day.FRIDAY
    console.log("Half day in office")
    break
  default:
    console.log("Don't know what day it is")
}

Перечисления TypeScript не обязательно сопоставлять с целочисленными значениями. Вы также можете сопоставить их со строками. Вот пример:

enum people {CYNTHIA = "Cynthia", DANNY = "Danny", MIKE = "Mike"}
let c = people.CYNTHIA, d = people.DANNY, m = people.MIKE
let numbers = new Map()
numbers.set(c, "2333")
numbers.set(d, "2334")
numbers.set(m, "2372")
for (let k of numbers.keys()) {
  console.log(k,numbers.get(k))
}

В этом примере перечисление отображает строки, а не целые числа, поэтому при отображении вывода строка, представляющая каждое имя, отображается вместе с добавочным номером телефона человека:

"Cynthia", "2333"
"Danny", "2334"
"Mike", "2372"

Перечисления никогда не требуются в программе, но часто могут облегчить чтение и анализ программы, особенно когда перечисляемые константы используются вместо целых значений.

Типы null, undefined, void и never

Чтобы завершить обсуждение типов данных TypeScript, я расскажу о четырех типах, которые обычно не аннотируются в программе, но могут автоматически назначаться TypeScript.

Первый из них null. Значение типа null в терминах переменной состоит в том, что у переменной отсутствует значение. Например, если вы пытаетесь присвоить строковой переменной текст из внешнего файла, но программа была остановлена ​​до завершения чтения файла, переменная будет иметь тип null. Трудно продемонстрировать, как переменная может быть набрана как null, так что вам просто придется поверить мне на слово.

Следующий тип в этом семействе — undefined. Многие программисты используют undefined и null взаимозаменяемо, но это не одно и то же. Тип undefined зарезервирован для переменных, которые были объявлены без аннотации типа, но не получили значения. Это легко продемонстрировать в программе:

let x
console.log(typeof x) // displays “undefined”

Тип x изменится, как только ему будет присвоено значение.

Тип void используется для функций, которые не возвращают значения. Вы можете использовать этот тип данных, чтобы специально аннотировать функцию, которая не возвращает значение, как в этом примере:

function greet(name) :void {
  console.log("Hello, " + name + "!");
}
let myName = "Cynthia"
greet(myName)

Последний тип данных в этой группе — never. Тип never называется нижним типом, что означает, что его можно присвоить чему угодно и безопасно использовать где угодно. Примером чего-то, что имеет тип never, является функция, которая никогда не возвращает значение, например та, которая определена как работающая в бесконечном цикле:

function infinite() {
  while(true) {
    // do anything
  }
}

На этом я завершаю обсуждение типов данных TypeScript. В следующей статье я начну обсуждение того, как функции используются в TypeScript.

Спасибо за чтение и, пожалуйста, ответьте на эту статью или напишите мне с вашими комментариями и предложениями.