用于将字符串枚举成员转换为枚举的Typescript函数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用于将字符串枚举成员转换为枚举的Typescript函数相关的知识,希望对你有一定的参考价值。

我想在Typescript中写这样的东西:

export function stringToEnum<T>(enumObj: T, str: string): keyof T {
    return enumObj[str];
}

并按如下方式使用:

enum MyEnum {
  Foo
}

stringToEnum<MyEnum>(MyEnum, 'Foo');

它将返回的地方

MyEnum.Foo

上面的函数按预期工作......但是输入错误。对于MyEnum中的参数stringToEnum<MyEnum>(MyEnum, 'Foo');,Typescript抱怨:

'typeof MyEnum'类型的参数不能分配给'MyEnum'类型的参数

这很有意义......不幸的是。关于如何解决这个问题的任何想法?

答案

您可以在不必编写函数的情况下完成所有操作:

enum Color {
    red,
    green,
    blue
}

// Enum to string
const redString: string = Color[Color.red];
alert(redString);

// String to enum
const str = 'red';
const redEnum: Color = Color[str];
alert(redEnum);

或者你可以玩得开心......

enum MyEnum {
  Foo,
  Bar
}

function stringToEnum<ET, T>(enumObj: ET, str: keyof ET): T{
    return enumObj[<string>str];
}

const val = stringToEnum<typeof MyEnum, MyEnum>(MyEnum, 'Foo');

// Detects that `foo` is a typo
const val2 = stringToEnum<typeof MyEnum, MyEnum>(MyEnum, 'foo');
另一答案
 stringToEnum(MyEnum, 'Foo');

只要放弃泛型,让打字稿就可以了。那是因为存储在MyEnum下的类型与Enum本身不匹配,但是它的值的联合类型:

 enum Test { A, B };

 const value: Test /* "A" | "B" */ = Test.A;
另一答案

你的签名有点混乱。如果您打算让方法返回枚举值,则返回类型应为T[keyof T]str param的类型也应该是keyof T以防止你传入无效的字符串,但是这将限制你传递字符串文字(或keyof T类型的良好类型变量,但不是string):

function stringToEnum<T>(enumObj: T, str: keyof T): T[keyof T]

然后要么不指定类型参数,要让编译器正确推断类型:

// type: Foo
// value: 0  
const result = stringToEnum(MyEnum, 'Foo');

或者你需要提供typeof MyEnum作为类型参数:

// type: Foo
// value: 0  
const result = stringToEnum<typeof MyEnum>(MyEnum, 'Foo');

如果你真的希望能够传入任意字符串枚举名,那么返回类型就是谎言:应该是T[keyof T] | undefined。如果enumObj[str]的类型是str并且启用了string编译器选项,那么在尝试noImplicitAny时也会遇到麻烦。

制作适用于枚举类型的通用函数还有一些功能,尤其是在运行时具有反向查找条目的数字枚举。看一下ts-enum-utilgithubnpm)源代码的灵感来源

以上是关于用于将字符串枚举成员转换为枚举的Typescript函数的主要内容,如果未能解决你的问题,请参考以下文章

在Angular 6模板语句中将字符串转换为Typescript枚举

枚举使用

使用泛型和简单地将字符串值转换为枚举时将字符串值转换为枚举时的混淆

java如何用方法toString()将枚举类型转换为字符串类型

JOOQ 使用转换器将字符串转换为枚举

将 Typescript 枚举从字符串转换为数字(角度)[重复]