我有以下枚举和接口:
enum EventId {
FOO = 'FOO',
BAR = 'BAR',
}
interface EventIdOptionsMap {
[EventId.FOO]: {
fooOption: string;
},
[EventId.BAR]: {
barOption: number;
}
}
interface EventRequest<K extends EventId> {
eventId: K;
options: EventIdOptionsMap[K];
}
现在,我可以创建一个对象并获得类型安全:
const blah: EventRequest<EventId.FOO> = {
eventId: EventId.FOO,
options: {
fooOption: 'testing',
bad: false, // this would fail
}
}
我必须键入两次EventId.FOO
位。我希望我可以创建一个实用程序函数,我只能指定它一次,如:
function createEvent<K extends EventId>(
eventId: K,
options: EventIdOptionsMap[K]
): EventRequest<K> {
return {
eventId,
options
};
}
但是我仍然需要指定两次才能使它工作:
const event = createEvent<EventId.FOO>(EventId.FOO, {
fooOption: 'testing'
});
// I can be SURE that `event` is implicity of type `EventRequest<EventId.FOO>`
但是,我仍然必须指定enum
两次,一次作为泛型类型,一次作为参数(用于运行时)。
是否有任何方法可以只指定它一次,作为泛型或作为参数,并且仍然生成我所追求的类型安全?
我觉得这个应该是可能的,因为enum
s是一种奇怪的类型,它们确实存在于运行时。所以我觉得应该是告诉TypeScript"这个类型是enum"的一种方式,所以我们应该能够在运行时使用它。或者类似的东西
我讨厌指定两次,我试图减少样板文件,因为我们会写很多这些对象。
是否有其他方法可以达到相同的目标?
你可以去掉type参数,TypeScript会发现的:
const event = createEvent(EventId.FOO, {
fooOption: 'testing'
});
看到