我有以下场景:
enum FieldsMap {
User = "user-name",
Password = "user-password",
Country = "user-country"
}
type Fields = "user-name" | "user-password" | "user-country";
Run Code Online (Sandbox Code Playgroud)
你可以看到Fields正在重复的值FieldsMap,有没有一种方法Fields可以使用值的FieldsMap,以避免重复?另外,我使用的FieldsMap是一个enum在这里,但我可以改变,如果有必要,我只是想避免使用字符串尽可能:
const onChangeHandler = (key: Fields, value: string) => {
switch (key) {
case FieldsMap.User:
// do something with `value`
break;
case FieldsMap.Password:
// do something with `value`
break;
case FieldsMap.Country:
// do something with `value`
break;
}
};
Run Code Online (Sandbox Code Playgroud)
jca*_*alz 12
TS4.1+ 更新:正如另一个答案所指出的,您现在可以使用模板文字类型来获取FieldsMap枚举值的字符串表示形式:
type Fields = `${FieldsMap}`;
// type Fields = "user-name" | "user-password" | "user-country"
Run Code Online (Sandbox Code Playgroud)
但重要的是要确保您确实需要它;enums的普通用例是您不希望对实际字符串文字值本身有太多依赖;对于名为 的枚举Foo,类型Foo已经是枚举值的联合,但它们被名义上对待,因此您不会意外地使用字符串代替它。如果您真的想使用字符串代替值,您可能一开始就不需要 an enum,而应该只使用其中包含字符串文字的对象。重点是:在使用之前确保这是您真正想要的。
只是将其写出来作为答案......在 TypeScript 中,枚举本质上已经具有您正在寻找的行为,而无需定义任何其他类型。
即,以下枚举定义:
enum Fields {
User = "user-name",
Password = "user-password",
Country = "user-country"
}
Run Code Online (Sandbox Code Playgroud)
带来到范围值命名Fields,与性质,其键User,Password以及Country和其值"user-name","user-password"和"user-country"分别,你也知道。该值使其进入运行时,如下所示:
const x = Fields.User; // makes it to the emitted JS
Run Code Online (Sandbox Code Playgroud)
并且类似于以下值:
const FieldsLike = {
User: "user-name",
Password: "user-password",
Country: "user-country"
} as const;
const xLike = FieldsLike.User; // makes it to the emitted JS;
Run Code Online (Sandbox Code Playgroud)
但它也带来了进入范围类型命名Fields,这相当于在工会中的属性值的Fields对象。当 JS 发出时,此类型会与类型系统的其余部分一起擦除,但可以在设计时通过类型注释和使用 IntelliSense 进行访问,如下所示:
const y: Fields = x; // the "Fields" annotation is the type
Run Code Online (Sandbox Code Playgroud)
并且类似于类型
type FieldsLike = (typeof FieldsLike)[keyof typeof FieldsLike];
// type FieldsLike = "user-name" | "user-password" | "user-country"
const yLike: FieldsLike = xLike; // the "FieldsLike" annotation is the type
Run Code Online (Sandbox Code Playgroud)
这是您正在寻找的类型;见下文。
顺便说一句,枚举还充当命名空间,为每个枚举成员导出类型:
const z: Fields.Password = Fields.Password; // type and value
Run Code Online (Sandbox Code Playgroud)
(所以Fields.Password左边是类型的名称,而Fields.Password右边是值的名称)。因此可访问的类型Fields类似于命名空间:
namespace FieldsLike {
export type User = typeof FieldsLike.User;
export type Password = typeof FieldsLike.Password;
export type Country = typeof FieldsLike.Country;
}
const zLike: FieldsLike.Password = FieldsLike.Password; // type and value
Run Code Online (Sandbox Code Playgroud)
呼,只是用该方法enum Fields { ... }定义给我们的行为 const FieldsLike = ...,type FieldsLike = ...以及namespace FieldsLike在一次所有。
让我们备份......你正在寻找的类型,Fields枚举下所有属性的联合,已经是一个名为Fields. (好吧,我改变了你的名字FieldsMap来Fields),你可以直接使用它:
const onChangeHandler = (key: Fields, value: string) => {
switch (key) {
case Fields.User:
// do something with `value`
break;
case Fields.Password:
// do something with `value`
break;
case Fields.Country:
// do something with `value`
break;
}
};
Run Code Online (Sandbox Code Playgroud)
好的,希望有帮助。祝你好运!
模板文字类型发布后,您可以使用:
type Fields = `${FieldsMap}` // "user-name" | "user-password" | "user-country"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3183 次 |
| 最近记录: |