跳至主要内容

从旧模式迁移

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

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

更新定义

Object.freeze

如果您正在使用 Object.freeze,则可以在对象的值满足以下条件时迁移到枚举:

  • 都是相同的原始类型,并且该类型为 booleanstringnumbersymbol
  • 都是字面量。
  • 不包含重复的值。

替换

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;

1export default enum Status {2  Active = 1,3  Paused = 2,4  Off = 3,5}
  • 检查以确保键名不以小写字母“a”到“z”开头(枚举中不允许)。如果它们以小写字母开头,则需要重命名成员名。
  • 删除枚举类型上任何 $Keys<...>$Values<...> 的使用,因为 Flow 枚举本身定义了一个类型(它的名称)。
  • 删除基于枚举的任何类型导出,因为您只需要导出 Flow 枚举。Flow 枚举既充当类型又充当值(类似于类)。

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

keyMirror

keyMirror 实用程序创建一个对象,其值与其键名相同。您可以使用基于字符串的枚举替换 keyMirror 的使用。

替换

import keyMirror from 'keyMirror';

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

export type StatusType = $Keys<typeof Status>;

export default Status;

1export default enum Status {2  Active,3  Paused,4  Off,5}
  • 检查以确保键名不以小写字母“a”到“z”开头(枚举中不允许)。如果它们以小写字母开头,则需要重命名成员名。
  • 删除枚举类型上任何 $Keys<...> 的使用,因为 Flow 枚举本身定义了一个类型(它的名称)。
  • 删除基于枚举的任何类型导出,您只需要导出 Flow 枚举。Flow 枚举既充当类型又充当值(类似于类)。

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

更新使用

修复类型导入

以前的模式要求您导出(然后导入)与枚举本身分离的类型。Flow 枚举既是类型又是值(类似于类),因此您只需要导出 Flow 枚举本身。由于现在只有一个导出,因此您只需要一个导入。阅读有关 导出枚举导入枚举 的更多信息。

如果您以前有

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

并且您已将其替换为

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

那么您也需要修复导入

如果同时导入类型和值

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

更改

import type {StatusType} from 'status';

import Status from 'status';

const myStatus: StatusType = Status.Active;

// Type import is deleted

import Status from 'status';

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

对于枚举的用户,如果您以前只导入了类型,则将类型导入更改为默认导入,而不是命名导入。

更改

import type {StatusType} from 'status';

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

// 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`

将枚举映射到其他值

有时您想从枚举值映射到其他值。以前,我们有时使用对象字面量来实现这一点。使用 Flow 枚举,请使用带有 switch 的函数。该 switch 经过详尽检查,因此 Flow 会确保您在添加或删除 Flow 枚举成员时更新映射。

替换此模式

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

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

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

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

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

强制转换为枚举类型

如果您以前使用以下方式从枚举的表示类型(例如 string)强制转换为枚举类型

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

更新 switch 语句

Flow 枚举在 switch 语句中经过详尽检查。当您切换枚举值时,您可能需要更新您的代码。在 switch 语句中详尽检查枚举 中阅读更多内容。

对枚举成员的操作

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