Reputation: 11870
I want create a interface that has a dynamic list of keys, that are based on the values of an enum.
Basically, it would look something like this:
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.
}
}
There are two things I don't know how to do here.
I'm happy to not use enums specifically if there is a handy solution that will do this.
Related reading:
This Typescript github issue: https://github.com/microsoft/TypeScript/issues/13042
If the answer is - 'This is not possible as...' can you please give a link to the best Github issue discussion(s) - and a summary of what the resolutions were? From the reading I have seen, this is a feature that a lot of people want.
Update: My current best solution involves creating an interface as the pseudo enum definition, and an implementation of that enum. Playground here. I'm not very happy with though.
Upvotes: 1
Views: 1119
Reputation: 36147
You can try with Type
like below, also modified object type to 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.
}
};
(or) with 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.
}
};
Upvotes: 1