枚举值的类型
Type of enum values
我可以获得表示接口键的类型:
interface I { a: string; b: string; }
const i: keyof I; // typeof i is "a" | "b"
有没有一种方法可以类似地获得表示枚举值的类型?
enum E { A = "a", B = "b" }
const e: ?; // typeof e is "a" | "b"
enum E { A = "a", B = "b" }
const e: keyof typeof E;
事实上,枚举的名称本身就是其值类型联合的别名。以下代码演示:
enum WaterType {
Lake = 0,
Ocean = 1,
River = 2,
Creek = 3,
};
let xxx: 0|1|2|3 = 2;
let yyy: WaterType = xxx; // OK
let zzz: 0|1|2|3 = yyy; // OK
枚举有点令人困惑,因为枚举的名称在某些上下文中指的是类型(如 0|1|2|3
),但在其他上下文中它指的是同名的对象。 WaterType
对象类似于此对象:
const WaterTypeObject = {
Lake : 0 as 0,
Ocean : 1 as 1,
River : 2 as 2,
Creek : 3 as 3,
};
而typeof WaterType
实际上与typeof WaterTypeObject
相同:
let aaa: typeof WaterType = WaterType;
let bbb: typeof WaterTypeObject = aaa; // OK
let ccc: typeof WaterType = bbb; // OK
在需要类型的上下文中,WaterType
表示 0|1|2|3
,但您可以编写 typeof WaterType
来获取枚举对象的类型:
// VS code reports: type WaterTypeString = "Lake" | "River" | "Ocean" | "Creek"
type WaterTypeString = keyof typeof WaterType;
// VS code reports: type WaterTypeNumbers = WaterType
// which really means type WaterTypeNumbers = 0|1|2|3
type WaterTypeNumbers = (typeof WaterType)[WaterTypeString];
只要确保不要写“keyof Enum”,例如keyof WaterType
和keyof number
一样,绝对不是你想要的
有趣的事实:keyof typeof WaterType
是个谎言。 WaterType
的键实际上是 "Lake"|"River"|"Ocean"|"Creek"|0|1|2|3
(例如 WaterType["Creek"]==3
和 WaterType[3]=="Creek"
。)
在 template literal 运算符的帮助下,可以将枚举的值列表推断为一种类型:
enum E { A = "a", B = "b" }
type EValue = `${E}`
// => type EValue = "a" | "b"
const value: EValue = "a" // => ✅ Valid
const valid: EValue = "b" // => ✅ Valid
const valid: EValue = "" // => Invalid
参考文章:Get the values of an enum dynamically
(免责声明:作者在此)
我可以获得表示接口键的类型:
interface I { a: string; b: string; }
const i: keyof I; // typeof i is "a" | "b"
有没有一种方法可以类似地获得表示枚举值的类型?
enum E { A = "a", B = "b" }
const e: ?; // typeof e is "a" | "b"
enum E { A = "a", B = "b" }
const e: keyof typeof E;
事实上,枚举的名称本身就是其值类型联合的别名。以下代码演示:
enum WaterType {
Lake = 0,
Ocean = 1,
River = 2,
Creek = 3,
};
let xxx: 0|1|2|3 = 2;
let yyy: WaterType = xxx; // OK
let zzz: 0|1|2|3 = yyy; // OK
枚举有点令人困惑,因为枚举的名称在某些上下文中指的是类型(如 0|1|2|3
),但在其他上下文中它指的是同名的对象。 WaterType
对象类似于此对象:
const WaterTypeObject = {
Lake : 0 as 0,
Ocean : 1 as 1,
River : 2 as 2,
Creek : 3 as 3,
};
而typeof WaterType
实际上与typeof WaterTypeObject
相同:
let aaa: typeof WaterType = WaterType;
let bbb: typeof WaterTypeObject = aaa; // OK
let ccc: typeof WaterType = bbb; // OK
在需要类型的上下文中,WaterType
表示 0|1|2|3
,但您可以编写 typeof WaterType
来获取枚举对象的类型:
// VS code reports: type WaterTypeString = "Lake" | "River" | "Ocean" | "Creek"
type WaterTypeString = keyof typeof WaterType;
// VS code reports: type WaterTypeNumbers = WaterType
// which really means type WaterTypeNumbers = 0|1|2|3
type WaterTypeNumbers = (typeof WaterType)[WaterTypeString];
只要确保不要写“keyof Enum”,例如keyof WaterType
和keyof number
一样,绝对不是你想要的
有趣的事实:keyof typeof WaterType
是个谎言。 WaterType
的键实际上是 "Lake"|"River"|"Ocean"|"Creek"|0|1|2|3
(例如 WaterType["Creek"]==3
和 WaterType[3]=="Creek"
。)
在 template literal 运算符的帮助下,可以将枚举的值列表推断为一种类型:
enum E { A = "a", B = "b" }
type EValue = `${E}`
// => type EValue = "a" | "b"
const value: EValue = "a" // => ✅ Valid
const valid: EValue = "b" // => ✅ Valid
const valid: EValue = "" // => Invalid
参考文章:Get the values of an enum dynamically (免责声明:作者在此)