简体   繁体   中英

How do I convert an integer from a Typescript enum to its key value as a type of the union of the keys?

I have two interfaces in Typescript, one of which uses an enum's integer values, and one of which uses the enum's keys:

enum foo {
    bar = 0,
    baz,
}

interface asNumbers {
    qux: foo
}

interface asStrings {
    quux: keyof typeof foo
}

I would like to take an object implementing asNumbers and convert it to an object implementing asStrings . I have the following code:

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

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

I receive the following error though on the stringyObject assignment though.

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

It is unclear to me how I can take that integer value and convert it into it's key in a typesafe manner (without resorting to more generic string types). Reproducible on typescript playground: Typescript playground link

You could define a function that provides some type safety while also meeting your use case:

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

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

If you wanted to be more generic, then you could define a function like this:

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

The compiler helps us in both cases, and will complain when we pass in an enum value that is not of type foo .

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

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

Here is a Fiddle for you that demonstrates both.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM