定义枚举
了解如何定义 Flow 枚举。正在寻找快速概览?看看 快速入门指南。
¥Learn how to define a Flow Enum. Looking for a quick overview? Check out the Quickstart Guide.
枚举声明是一个声明。它的名称定义了一个值(从该值到 访问其成员,并调用它的 方法)和一个类型(对于其成员的类型可以是 用作注释)。
¥An enum declaration is a statement. Its name defines both a value (from which to access its members, and call its methods), and a type (which can be used as an annotation for the type of its members).
枚举成员必须全部属于同一类型,并且这些成员可以是以下四种类型之一:字符串、数字、布尔值 和 符号。
¥Enum members must all be of the same type, and those members can be one of four types: string, number, boolean, and symbol.
每个枚举都有一些共同的属性:
¥Every enum has some common properties:
一致的成员类型
¥Consistent member type
枚举成员的类型必须一致。例如,你不能在一个枚举中混合使用 string
和 number
成员。它们必须全部是字符串、数字或布尔值(你不为基于 symbol
的枚举提供值)。
¥The type of the enum members must be consistent. For example, you can’t mix string
and number
members in one enum.
They must all be strings, numbers, or booleans (you do not provide values for symbol
based enums).
成员名起始字符
¥Member name starting character
成员名称必须是有效的标识符(例如不能以数字开头),并且不能以小写字母 a
到 z
开头。以这些字母开头的名称保留用于枚举 方法(例如 Status.cast(...)
)。
¥Member names must be valid identifiers (e.g. not start with numbers), and must not start with lowercase a
through z
.
Names starting with those letters are reserved for enum methods (e.g. Status.cast(...)
).
这是不允许的:
¥This is not allowed:
1enum Status {2 active, // Error: names can't start with lowercase 'a' through 'z'3}
独特的成员名称
¥Unique member names
成员名称必须是唯一的。这是不允许的:
¥Member names must be unique. This is not allowed:
1enum Status {2 Active,3 Active, // Error: the name 'Active` was already used above4}
字面量成员值
¥Literal member values
如果为枚举成员指定值,则它必须是字面量(字符串、数字或布尔值),而不是计算值。这是不允许的:
¥If you specify a value for an enum member, it must be a literal (string, number, or boolean), not a computed value. This is not allowed:
1enum Status {2 Active = 1 + 2, // Error: the value must be a literal3}
独特的成员值
¥Unique member values
成员值必须是唯一的。这是不允许的:
¥Member values must be unique. This is not allowed:
1enum Status {2 Active = 1,3 Paused = 1, // Error: the value has already been used above4}
固定于声明
¥Fixed at declaration
枚举是不可扩展的,因此在代码运行时你无法添加新成员。在运行时,枚举成员值无法更改,也无法删除成员。通过这种方式,它们就像一个冻结的对象。
¥An enum is not extendable, so you can’t add new members after the fact while your code is running. At runtime, enum member values can’t change and the members can’t be deleted. In this way they act like a frozen object.
字符串枚举
¥String enums
字符串枚举是默认值。如果你不指定 of
子句(例如 enum Status of number {}
、enum Status of symbol {}
等),也不指定任何值(例如 enum Status {Active = 1}
),则定义将默认为字符串枚举。
¥String enums are the default. If you don’t specify an of
clause (e.g. enum Status of number {}
, enum Status of symbol {}
, etc.),
and do not specify any values (e.g. enum Status {Active = 1}
) then the definition will default to be a string enum.
与其他类型的枚举(例如数字枚举)不同,你可以为枚举成员指定值,也可以不指定值并允许使用默认值。
¥Unlike the other types of enums (e.g. number enums), you can either specify values for the enum members, or not specify values and allow them to be defaulted.
如果你没有为枚举成员指定值,它们将默认为与成员名称相同的字符串。
¥If you don’t specify values for your enum members, they default to strings which are the same as the name of your members.
1enum Status {2 Active,3 Paused,4 Off,5}
是相同的:
¥Is the same as:
1enum Status {2 Active = 'Active',3 Paused = 'Paused',4 Off = 'Off',5}
你必须一致地为所有成员指定值,或者不为任何成员指定值。这是不允许的:
¥You must consistently either specify the value for all members, or none of the members. This is not allowed:
1enum Status {2 Active = 'active',3 Paused = 'paused',4 Off, // Error: you must specify a value for all members (or none of the members)5}
或者,你可以使用 of
子句:
¥Optionally, you can use an of
clause:
1enum Status of string {2 Active,3 Paused,4 Off,5}
如果没有 of
子句,我们会根据枚举的值推断其类型。使用 of
子句将确保如果你使用不正确的值,错误消息将始终将其解释为该类型的枚举。
¥We infer the type of the enum based on its values if there is no of
clause.
Using an of
clause will ensure that if you use incorrect values, the error message will always interpret it as an enum of that type.
数字枚举
¥Number enums
数字枚举必须指定其值。
¥Number enums must have their values specified.
你可以像这样指定一个数字枚举:
¥You can specify a number enum like this:
1enum Status {2 Active = 1,3 Paused = 2,4 Off = 3,5}
你也可以选择使用 of
子句。这不会影响有效 Flow 枚举的类型检查行为,它只是确保所有枚举成员都是 number
作为定义站点。
¥Optionally, you can use an of
clause.
This does not affect the type-checking behavior of a valid Flow Enum,
it just ensures that all enum members are number
s as the definition site.
1enum Status of number {2 Active = 1,3 Paused = 2,4 Off = 3,5}
我们不允许默认数字枚举(与其他一些语言不同),因为如果添加或删除此类枚举中间的成员,则所有后续成员值都将更改。这可能是不安全的(例如推送安全、序列化、日志记录)。要求用户明确重新编号可以让他们思考这样做的后果。
¥We do not allow defaulting of number enums (unlike some other languages), because if a member from the middle of such an enum is added or removed, all subsequent member values would be changed. This can be unsafe (e.g. push safety, serialization, logging). Requiring the user to be explicit about the renumbering makes them think about the consequences of doing so.
提供的值必须是数字字面量。负数不是 JS 中的字面量,但自 Flow 版本 0.234 以来,我们也允许负数初始化器。
¥The value provided must be a number literal. Negative numbers are not literals in JS, but since Flow version 0.234 we allow negative number initializers as well.
示例
¥Example
≥0.234:
1enum Status {2 Active = 1,3 Paused = 0,4 Off = -1,5}
布尔枚举
¥Boolean enums
布尔枚举必须指定其值。布尔枚举只能有两个成员。
¥Boolean enums must have their values specified. Boolean enums can only have two members.
你可以像这样指定布尔枚举:
¥You can specify a boolean enum like this:
1enum Status {2 Active = true,3 Off = false,4}
你也可以选择使用 of
子句。这不会影响有效 Flow 枚举的类型检查行为,它只是确保所有枚举成员都是 boolean
作为定义站点。
¥Optionally, you can use an of
clause.
This does not affect the type-checking behavior of a valid Flow Enum,
it just ensures that all enum members are boolean
s as the definition site.
1enum Status of boolean {2 Active = true,3 Off = false,4}
符号枚举
¥Symbol enums
符号枚举不能指定其值。每个成员都是一个新符号,符号描述设置为成员的名称。你必须将 of
子句与符号枚举一起使用,以将它们与字符串枚举区分开来,字符串枚举是省略值时的默认值。
¥Symbol enums can’t have their values specified. Each member is a new symbol, with the symbol description set to the name of the member.
You must use the of
clause with symbol enums, to distinguish them from string enums, which are the default when omitting values.
你可以像这样指定符号枚举:
¥You can specify a symbol enum like this:
1enum Status of symbol {2 Active,3 Paused,4 Off,5}
具有未知成员的 Flow 枚举
¥Flow Enums with Unknown Members
你可以通过在声明末尾添加 ...
来指定枚举包含 "未知成员":
¥You can specify that your enum contains "unknown members" by adding a ...
to the end of the declaration:
1enum Status {2 Active,3 Paused,4 Off,5 ...6}7const status: Status = Status.Active;8
9switch (status) {10 case Status.Active: break;11 case Status.Paused: break;12 case Status.Off: break;13}
使用此选项时,即使检查了所有已知的枚举成员,Flow 在 切换枚举 时也始终需要 default
。default
检查你未明确列出的 "未知" 成员。
¥When this is used, Flow will always require a default
when switching over the enum,
even if all known enum members are checked. The default
checks for "unknown" members you haven't explicitly listed.
当枚举值跨越某些边界并且每一侧的枚举声明可能具有不同的成员时,此功能非常有用。例如,在客户端和服务器上使用的枚举定义:可以添加一个枚举成员,服务器可以立即看到该成员,但可以将其发送到尚不知道新成员的过时客户端。
¥This feature is useful when an enum value crosses some boundary and the enum declaration on each side may have different memebers. For example, an enum definition which is used on both the client and the server: an enum member could be added, which would be immediately seen by the server, but could be sent to an outdated client which isn't yet aware of the new member.
一个用例是 GraphQL 枚举 的 JS 输出:可以使用具有未知成员的 Flow 枚举来代替添加的 '%future added value'
成员。
¥One use case for this would be the JS output of GraphQL Enums:
Flow Enums with unknown members could be used instead of the added '%future added value'
member.
运行时枚举
¥Enums at runtime
枚举在运行时作为值存在。我们使用 Babel 变换 将 Flow Enum 声明转换为对 枚举运行时 的调用(在 启用枚举文档 中了解更多信息)。我们使用运行时,因此所有枚举都可以共享枚举 方法 的实现。
¥Enums exist as values at runtime. We use a Babel transform to transform Flow Enum declarations into calls to the enums runtime (read more in the enabling enums documentation). We use a runtime so all enums can share an implementation of the enum methods.
我们使用 Object.create(null)
作为枚举的原型(具有枚举方法),因此 Object.prototype
中的属性不会污染枚举。枚举对象唯一自己的属性是枚举成员。成员是不可枚举的(使用 .members()
方法)。整个枚举对象被冻结,因此无法修改。
¥We use Object.create(null)
for enums' prototype (which has the enum methods), so properties in Object.prototype
will not pollute enums.
The only own properties of the enum object are the enum members. The members are non-enumerable (use the .members()
method for that).
The entire enum object is frozen, so it cannot be modified.
风格指南
¥Style guide
命名枚举
¥Naming enums
我们鼓励你在 PascalCase
中定义枚举名称,遵循其他类型的命名约定。所有大写的名称(例如 STATUS
)都难以阅读并且不鼓励使用。
¥We encourage you to define enum names in PascalCase
, following the naming conventions of other types. All caps names (e.g. STATUS
) are harder to read and discouraged.
我们鼓励你以单数命名枚举。例如。Status
,不是 Statuses
。就像 true
和 false
的类型是 boolean
,而不是 booleans
。
¥We encourage you to name enums in the singular. E.g. Status
, not Statuses
. Just like the type of true
and false
is boolean
, not booleans
.
不要将 Enum
附加到名称中(例如,不要将枚举命名为 StatusEnum
)。这是不必要的,就像我们不会将 Class
附加到每个类名,将 Type
附加到每个类型别名一样。
¥Don't append Enum
to the name (e.g. don't name your enum StatusEnum
). This is unnecessary, just like we don't append Class
to every class name, and Type
to every type alias.
命名枚举成员
¥Naming enum members
我们鼓励你在 PascalCase
中定义枚举成员名称。所有大写的名称(例如 ACTIVE
)都难以阅读并且不鼓励使用。此外,由于 Flow 强制要求这些都是常量,因此你不需要使用名称来向程序员表明该意图。
¥We encourage you to define enum member names in PascalCase
. All caps names (e.g. ACTIVE
) are harder to read and discouraged.
Additionally, since Flow enforces that these are constants, you don't need to use the name to signal that intent to the programmer.
也可以看看:关于 枚举成员名称起始字符 的规则。
¥See also: the rule about enum member name starting characters.
不要创建单独的类型
¥Don't create a separate type
Flow Enum 与类一样,既是类型又是值。你不需要创建单独的类型别名,可以使用枚举名称。
¥A Flow Enum, like a class, is both a type and a value. You don't need to create a separate type alias, you can use the enum name.
使用点访问来访问成员
¥Use dot access for accessing members
与 const {Active} = Status;
相比,更喜欢 Status.Active
。这使得通过文本搜索更容易找到枚举的用途,并使读者更清楚枚举涉及什么。此外,这对于 涉及枚举的 switch 语句 是必需的。
¥Prefer Status.Active
vs. const {Active} = Status;
. This makes it easier find uses of the enum with text search, and makes it clearer to the reader what enum is involved.
Additionally, this is required for switch statements involving enums.