Skip to main content

从旧版模式迁移

了解如何从旧版 JavaScript 枚举模式(例如 Object.freeze)迁移到 Flow 枚举。

¥Learn how to migrate to Flow Enums from legacy JavaScript enum patterns like Object.freeze.

首先,学习如何 更新枚举定义站点,然后学习如何 更新导入和使用枚举的文件

¥First, learn how to update the enum definition site, and next learn how to update files that import and use the enum.

更新定义

¥Updating definitions

Object.freeze

如果你使用的是 Object.freeze,并且对象的值为:,则可以迁移到枚举:

¥If you are using Object.freeze, you can migrate to an enum if the values of the object are:

  • 都是相同的原始类型,并且该类型是 booleanstringnumbersymbol

    ¥All the same primitive type, and that type is boolean, string, number, or symbol.

  • 都是字面意思。

    ¥All literals.

  • 不包含重复值。

    ¥Contain no duplicate values.

代替

¥Replace

1const Status = Object.freeze({2  Active: 1,3  Paused: 2,4  Off: 3,5});6
7export type StatusType = $Values<typeof Status>;8
9export default Status;

¥with

1export default enum Status {2  Active = 1,3  Paused = 2,4  Off = 3,5}
  • 检查以确保键名称不以小写“a”-“z”开头(枚举中不允许)。如果这样做,你将需要重命名成员名称。

    ¥Check to ensure that the key names do not start with lowercase ‘a’-‘z’ (disallowed in enums). If they do, you’ll need to rename the member names.

  • 删除枚举类型上 $Keys<...>$Values<...> 的任何使用,不再需要这些,因为 Flow 枚举定义了类型本身(其名称)。

    ¥Remove any usage of $Keys<...> or $Values<...> on the enum type, these are no longer needed as a Flow Enum defines a type itself (its name).

  • 删除基于枚举的任何类型导出,因为你只需要导出 Flow 枚举。Flow 枚举既充当类型又充当值(如类)。

    ¥Delete any type exports based on the enum, as you just need to export the Flow Enum. A Flow Enum acts as both a type and a value (like a class).

然后,看一下 如何更新导入和使用枚举的文件

¥Then, take a look at how to update files that import and use the enum.

keyMirror

keyMirror 实用程序创建一个对象,其值是其键名称的镜像。你可以将 keyMirror 用法替换为基于字符串的枚举。

¥The keyMirror utility creates an object whose values are mirrors of its key names. You can replace keyMirror usage with a string based enum.

代替

¥Replace

import keyMirror from 'keyMirror';

const Status = keyMirror({
Active: null,
Paused: null,
Off: null,
});

export type StatusType = $Keys<typeof Status>;

export default Status;

¥with

1export default enum Status {2  Active,3  Paused,4  Off,5}
  • 检查以确保键名称不以小写“a”-“z”开头(枚举中不允许)。如果这样做,你将需要重命名成员名称。

    ¥Check to ensure that the key names do not start with lowercase ‘a’-‘z’ (disallowed in enums). If they do, you’ll need to rename the member names.

  • 删除枚举类型上 $Keys<...> 的任何使用,不再需要它,因为 Flow 枚举定义了类型本身(其名称)。

    ¥Remove any usage of $Keys<...> on the enum type, it's no longer needed as a Flow Enum defines a type itself (its name).

  • 删除任何基于枚举的类型导出,只需导出 Flow 枚举即可。Flow 枚举既充当类型又充当值(如类)。

    ¥Delete any type exports based on the enum, you just need to export the Flow Enum. A Flow Enum acts as both a type and a value (like a class).

然后,看一下 如何更新导入和使用枚举的文件

¥Then, take a look at how to update files that import and use the enum.

更新用法

¥Updating usage

固定型导入

¥Fix type imports

以前的模式要求你导出(然后导入)与枚举本身分开的类型。Flow 枚举既是类型又是值(就像类),因此你只需导出 Flow 枚举本身。由于现在有一项导出,因此你只需要一项导入。了解有关 导出枚举导入枚举 的更多信息。

¥Previous patterns required you to export (and then import) a type separate from the enum itself. Flow Enums are both types and values (like a class), so you just need to export the Flow Enum itself. Since there is now one export, you only need one import. Read more about exporting enums and importing enums.

如果你以前有过:

¥If you previously had:

1const Status = Object.freeze({2  Active: 1,3  Paused: 2,4  Off: 3,5});6export type StatusType = $Values<typeof Status>;7export default Status;

并且你已将其替换为:

¥And you've replaced it with:

1export default enum Status {2  Active = 1,3  Paused = 2,4  Off = 3,5}

然后你还需要修复导入:

¥Then you need to fix the imports as well:

如果类型和值都导入了

¥If both type and value were imported

对于枚举的用户,如果你之前同时导入了类型和值,则可以删除所使用的类型导入和更新注释。

¥For a user of the enum, if you previously imported both the type and the value, you can delete the type import and update annotations used.

改变

¥Change

import type {StatusType} from 'status';

import Status from 'status';

const myStatus: StatusType = Status.Active;

¥to

// Type import is deleted

import Status from 'status';

const myStatus: Status = Status.Active; // Changed type annotation to just `Status`
如果仅导入类型

¥If only the type was imported

对于枚举的用户,如果你之前仅导入了类型,请将类型导入更改为默认导入而不是命名导入。

¥For a user of the enum, if you previously imported just the type, change the type import to a default import rather than a named import.

改变

¥Change

import type {StatusType} from 'status';

function isActive(status: StatusType) { ... }

¥to

// Remove the braces `{` `}` and changed the name - this is a default import now
import type Status from 'status';

function isActive(status: Status) { ... } // Changed type annotation to just `Status`

将枚举映射到其他值

¥Mapping enums to other values

有时你想从枚举值映射到其他值。以前,我们有时为此使用对象字面量。对于 Flow 枚举,请使用带有 switch 的函数。开关是 彻底检查,因此 Flow 将确保你在添加或删除 Flow Enum 成员时更新映射。

¥Sometimes you want to map from an enum value to some other value. Previously, we sometimes used object literals for this. With Flow Enums, use a function with a switch instead. The switch is exhaustively checked, so Flow will ensure you update your mapping when you add or remove Flow Enum members.

替换这个图案

¥Replace this pattern

const STATUS_ICON: {[Status]: string} = {
[Status.Active]: 'green-checkmark',
[Status.Paused]: 'grey-pause',
[Status.Off]: 'red-x',
};
const icon = STATUS_ICON[status];

¥with

function statusIcon(status: Status): string {
switch (status) {
case Status.Active:
return 'green-checkmark';
case Status.Paused:
return 'grey-pause';
case Status.Off:
return 'red-x';
}
}
const icon = statusIcon(status);

了解有关 将枚举映射到其他值 的更多信息。

¥Read more about mapping enums to other values.

用作表示类型(例如字符串)

¥Usage as the representation type (e.g. a string)

你不能直接使用 Flow 枚举作为其表示类型(例如 string)。如果你收到有关使用枚举作为其表示类型的 Flow 错误,请首先尝试重构你的代码,以便它需要枚举类型而不是表示类型(例如,将注释从 string 更改为 Status)。如果你确实想使用枚举作为其表示类型,则可以添加显式强制转换。参见 转换为再现类型

¥You can't use a Flow Enum directly as its representation type (e.g. a string). If you get Flow errors about using an enum as its representation type, first try to refactor your code so that it expects the enum type instead of the representation type (e.g. change annotations from string to Status). If you really want to use the enum as its representation type, you can add in explicit casts. See casting to represetation type.

转换为枚举类型

¥Casting to the enum type

如果你之前从枚举的表示类型(例如 string)转换为枚举类型,如下所示:

¥If before you cast from an enum's representation type (e.g. string) to the enum type with something like this:

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);

你现在可以使用 投掷 方法:

¥You can now just use the cast method:

Status.cast(x);

更新 switch 语句

¥Update switch statements

Flow 枚举在 switch 语句中进行了详尽的检查。当你切换枚举值时,你可能需要更新代码。欲了解更多内容,请访问 详尽地检查 switch 语句中的枚举

¥Flow Enums are exhaustively checked in switch statements. You might need to update your code when you are switching over an enum value. Read more at exhaustively checking enums in switch statements.

对枚举成员的操作

¥Operations over enum members

如果你之前使用 Object.valuesObject.keysfor-in 循环等功能来获取和操作枚举成员,则可以改用 成员方法

¥If previously you used functionality like Object.values, Object.keys, or for-in loops to get and operate on the enum members, you can use the members method instead.