Представляем Flow Enums

Как было объявлено в более раннем сообщении, Flow представит новые языковые функции. Первый - Flow Enums, функция выбора, которая позволяет вам определять фиксированный набор констант, которые создают свой собственный тип. Если вы знакомы с TypeScript, вы можете взглянуть на наше сравнение перечислений Flow и перечислений TypeScript.

Перечисления потока предоставляют несколько преимуществ по сравнению с существующими шаблонами, подобными перечислениям (например, Object.freeze и объединения строковых литералов): сокращение повторений за счет определения значения и типа в одном определении, включение новых функций, таких как типобезопасная функция приведение, повышение безопасности за счет требования исчерпывающая проверка в switch операторах и гарантирует хорошую производительность Flow.

В Facebook мы используем Flow Enums более года, и в нашей кодовой базе более 5000 Flow Enum.

В документации есть полная информация о том, как включить, определить и использовать Flow Enum. Вот краткий обзор:

Обзор

В отличие от других функций Flow, перечисления существуют как значения во время выполнения, так и как типы.

Определите перечисление со строковыми значениями, которое отражает имена членов:

enum Status {
  Active,
  Paused,
  Off,
}

Определите перечисление с числовыми значениями:

enum Status {
  Active = 1,
  Paused = 2,
  Off = 3,
}

Раньше при использовании Object.freeze вам приходилось определять объект со значениями и типом отдельно, что является более подробным.

Получите доступ к члену перечисления и используйте имя перечисления в качестве аннотации типа:

const status: Status = Status.Active;

Раньше имя типа и имя объекта перечисления были бы разными, теперь у нас может быть одно имя и один импорт как для типа, так и для значения.

Безопасно приведите string к члену перечисления (или undefined, если член не действительный):

const couldBeStatus: Status | void = Status.cast(someString);

Раньше вам приходилось создавать оператор switch с каждым членом перечисления как case, чтобы преобразовать произвольный _6 _ / _ 7_ в значение перечисления безопасным для типов способом.

Проверьте перечисление в switch statement полностью - мы гарантируем, что вы проверите всех участников:

// ERROR: Incomplete exhaustive check: the member `Off` of enum
// `Status` has not been considered in check of `status`
switch (status) {
  case Status.Active: ...; break;
  case Status.Paused: ...; break;
  // We forgot to add `case: Status.Off:` here,
  // resulting in error above
}

Перечисления потока не являются синтаксисом для типов объединения. Это отдельный тип, и каждый член Flow Enum имеет один и тот же тип. Типы больших объединений могут вызвать проблемы с производительностью, поскольку Flow должен рассматривать каждый член как отдельный тип. С Flow Enums, независимо от того, насколько велико ваше перечисление, Flow всегда будет демонстрировать хорошую производительность, поскольку у него есть только один тип, который нужно отслеживать.

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

Включение перечислений потоков

Вы можете прочитать полную документацию о том, как включить Flow Enums в вашем проекте. Суммируя:

  • Обновите свои инструменты (например, Prettier, Babel, Flow и т. Д.) Для поддержки нового синтаксиса
  • Добавьте babel-plugin-transform-flow-enums в свой конвейер преобразования Babel
  • Добавьте модуль flow-enums-runtime к вашим производственным зависимостям (вызывается из вывода преобразования)
  • Включите в своем .flowconfig, добавив enums=true в раздел [options]

Перенос устаревших шаблонов

Затем вы можете перейти от устаревших шаблонов в своей кодовой базе. Например, если раньше у вас были:

const Status = Object.freeze({
  Active: 1,
  Paused: 2,
  Off: 3,
});
type StatusType = $Values<typeof Status>;
const status: StatusType = Status.Active;

Вы можете использовать:

enum Status {
  Active = 1,
  Paused = 2,
  Off = 3,
}
const status: Status = Status.Active;

Если до этого вы привели к типу перечисления следующим образом:

function castToStatus(input: number): StatusType | void {
  switch(input) {
    case 1: return Status.Active;
    case 2: return Status.Paused;
    case 3: return Status.Off;
    default: return undefined;
  }
}
castToStatus(x)

Теперь вы можете просто использовать:

Status.cast(x)

Более

Прочтите документацию для получения дополнительной информации.