如何将Typescript枚举中的整数转换为其键值作为键的并集类型?

时间:2017-08-21 23:40:09

标签: typescript

我在Typescript中有两个接口,其中一个使用枚举的整数值,其中一个使用枚举的键:

enum foo {
    bar = 0,
    baz,
}

interface asNumbers {
    qux: foo
}

interface asStrings {
    quux: keyof typeof foo
}

我想采用实现asNumbers的对象并将其转换为实现asStrings的对象。我有以下代码:

const numberObject: asNumbers = {
    qux: foo.bar
}

const stringyObject: asStrings = {
    quux: foo[numberObject.qux] 
}

虽然我在stringyObject赋值时收到以下错误。

Type '{ quux: string; }' is not assignable to type 'asStrings'.
Types of property 'quux' are incompatible.
Type 'string' is not assignable to type '"bar" | "baz"'.

我不清楚如何获取该整数值并以类型安全的方式将其转换为它的键(不使用更通用的string类型)。可以在打字稿操场上重现:Typescript playground link

1 个答案:

答案 0 :(得分:0)

您可以定义一个提供某种类型安全性的功能,同时满足您的使用案例:

const stringyObject: asStrings = {
    quux: getFooProp[numberObject.qux] 
}

function getFooProp(i: foo): (keyof typeof foo) { 
    return foo[i] as (keyof typeof foo);
}

如果你想更通用,那么你可以定义一个这样的函数:

interface NumericEnum {
    [id: number]: string
}

function getEnumProp<T extends NumericEnum, K extends keyof T>(
    e: T,
    i: T[K]): (keyof T) { 

    return e[i] as (keyof T);
}

编译器在两种情况下都会帮助我们,并且当我们传入一个非foo类型的枚举值时会抱怨。

// Works
getEnumProp(foo, foo.bar);

// Argument of type 'foo2.bar' 
// is not assignable to parameter of type 'foo'.
getEnumProp(foo, foo2.bar); 

http://plnkr.co/edit/f1Eq2OGKTuCLgI6KXn1b?p=preview证明了这两点。