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

时间:2018-01-25 19:20:21

标签: javascript typescript enums

我想在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会抱怨:

  

MyEnum&#39;类型&#39;类型的争论不能分配给参数   输入&#39; MyEnum&#39;

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

3 个答案:

答案 0 :(得分:2)

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

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');

答案 1 :(得分:1)

 stringToEnum(MyEnum, 'Foo');

放弃通用,让打字稿做到这一点。 那是因为存储在MyEnum下的类型与Enum本身不匹配,但是它是值的联合类型:

 enum Test { A, B };

 const value: Test /* "A" | "B" */ = Test.A;

答案 2 :(得分:0)

你的签名有点混乱。如果您打算让方法返回枚举值,则返回类型应为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)的源代码以获取灵感