首页 > 解决方案 > 使用枚举定义接口上的键列表

问题描述

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

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

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. 我将如何为通用枚举做动态键列表?

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

相关阅读:

这个 Typescript github 问题:https ://github.com/microsoft/TypeScript/issues/13042

如果答案是——“这是不可能的……”你能否提供一个指向最佳 Github 问题讨论的链接——以及解决方案的摘要?从我看到的阅读来看,这是很多人想要的功能。

更新:我目前最好的解决方案包括创建一个接口作为伪枚举定义,以及该枚举的实现。这里的操场。不过我不是很满意。

标签: typescriptgenericsenums

解决方案


您可以尝试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 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.
    }
};

推荐阅读