How to build a type from enum values in TypeScript?

后端 未结 3 1577
时光取名叫无心
时光取名叫无心 2021-01-17 10:53

Given the following:

enum FooKeys {
  FOO = \'foo\',
  BAR = \'bar\',
}

I\'d like to make an interface like this one, but instead of defini

相关标签:
3条回答
  • 2021-01-17 11:28

    Yes, you can use enum values as keys. And you can use a mapped type like the standard library's Record<K, V> to prevent repetition:

    enum FooKeys {
      FOO = 'foo',
      BAR = 'bar',
    }
    
    // probably all you need, but it's a type alias
    type FooType = Record<FooKeys, string>;
    
    // if you need an interface instead you can do this
    interface FooInterface extends FooType {};
    

    And you can verify that it works:

    declare const foo: FooInterface;
    foo.foo; // okay
    foo[FooKeys.FOO]; // okay
    
    foo.bar; // okay
    foo[FooKeys.BAR]; // okay
    
    foo.baz; // error
    

    Does that work for you? Good luck!

    0 讨论(0)
  • 2021-01-17 11:29

    @hackape 's solution is great, but I found minimal duplication extending his solution as below:

    type ReverseMap<T extends Record<keyof T, any>> = {
      [V in T[keyof T]]: {
        [K in keyof T]: T[K] extends V ? K : never;
      }[keyof T];
    }
    
    const Map = {
      'FOO': "foo" as "foo",
      'BAR': "bar" as "bar",
    }
    
    const reverseMap: ReverseMap<typeof Map> = Object.entries(Map).reduce((rMap, [k, v]) => {
      rMap[v] = k;
      return rMap;
    }, {} as any);
    
    export type Values = keyof typeof reverseMap; // 'foo' | 'bar';
    

    ReverseMap implementation is well explained here

    0 讨论(0)
  • 2021-01-17 11:31

    yes?

    enum FooKeys {
      FOO = 'foo',
      BAR = 'bar',
    }
    
    interface Foo {
      foo: string
      bar: string
    }
    
    class Test implements Foo {
        public foo: string = FooKeys.FOO;
        public bar: string = FooKeys.BAR;
    }
    
    0 讨论(0)
提交回复
热议问题