使用枚举定义接口上的键列表

时间:2019-05-30 02:00:53

标签: typescript generics enums

我想创建一个具有动态键列表的接口,该键基于枚举的值。

基本上,它看起来像这样:

enum MyEnum {
    foo = "foo", 
    bar ="bar"
}

interface MyInterface {  //A generic on this line
    id: string; 
    objects: {
        [key: string] : string;   //Instead of mapping to string,
                                  // map to the values of the enum
    }
}

const x : MyInterface<MyEnum> = {
    id: "123", 
    objects: {
        foo: "hello", 
        bar: "world", 
    }
}

//Now I can access the values with: 
console.log(x.objects[MyEnum.foo]); 

const y : MyInterface<MyEnum> = {
    id: "123", 
    objects: {
        foo: "hello", //Should give typeScript warning - bar doesn't exist. 
    }
}

有两件事我在这里不知道该怎么做。

  1. 如何定义泛型必须为枚举类型?
  2. 如何为通用枚举创建动态键列表?

如果有方便的解决方案可以做到这一点,我很高兴不专门使用枚举。

相关阅读:

此打字稿github问题:https://github.com/microsoft/TypeScript/issues/13042

如果答案是-'这不可能...',请您链接到最佳的Github问题讨论-以及决议的摘要?从我看过的书中,这是很多人想要的功能。

更新:我当前的最佳解决方案包括创建一个接口作为伪枚举定义以及该枚举的实现。 Playground here。我不是很满意。

1 个答案:

答案 0 :(得分:1)

您可以尝试使用Type,如下所示,还可以将对象类型修改为Record<k,T>

type MyEnum = "foo" | "bar";

interface MyInterface<K extends MyEnum, T> {
    id: string;
    objects: Record<K, T>;
}

const x: MyInterface<MyEnum, string> = {
    id: "123",
    objects: {
        foo: "hello",
        bar: "world"
    }
};

//Now I can access the values with:
console.log(x.objects.notAvailable); // Property 'notAvailable' does not exist on type 'Record<MyEnum, string>'
console.log(x.objects.foo); //ok

const y: MyInterface<MyEnum, string> = {
    id: "123",
    objects: {
        foo: "hello" //Should give typeScript warning - bar doesn't exist.
    }
};

(或)和Enum

enum MyEnum {
    "foo" = "foo",
    "bar" = "bar"
}

interface MyInterface<K extends MyEnum, T> {
    id: string;
    objects: Record<K, T>;
}

const x: MyInterface<MyEnum, string> = {
    id: "123",
    objects: {
        foo: "hello",
        bar: "world"
    }
};

//Now I can access the values with:
console.log(x.objects.notAvailable); // Property 'notAvailable' does not exist on type 'Record<MyEnum, string>'
console.log(x.objects.bar); //ok

const y: MyInterface<MyEnum, string> = {
    id: "123",
    objects: {
        foo: "hello" //Should give typeScript warning - bar doesn't exist.
    }
};