从旧模式迁移
了解如何从旧的 JavaScript 枚举模式(如 Object.freeze
)迁移到 Flow 枚举。
首先,了解如何 更新枚举定义站点,然后了解如何 更新导入和使用枚举的文件。
更新定义
Object.freeze
如果您正在使用 Object.freeze
,则可以在对象的值满足以下条件时迁移到枚举:
- 都是相同的原始类型,并且该类型为
boolean
、string
、number
或symbol
。 - 都是字面量。
- 不包含重复的值。
替换
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.values
、Object.keys
或 for-in
循环等功能来获取和操作枚举成员,则可以使用 members 方法 代替。