作为事件函数的键到值的TypescriptMap

nlejzf6q  于 2023-04-07  发布在  TypeScript
关注(0)|答案(1)|浏览(108)

我试图用事件的关键存在类型和事件的有效负载值来创建一个Map,但是我不能让回调接收正确事件的参数

type DeviceEvent<T extends string, Data> = {
  type: T;
  data: Data;
}

type EventA = DeviceEvent<"event_a", {some: string}>
type EventB = DeviceEvent<"event_b", {some_other: string}>
type EventC = DeviceEvent<"event_c", {some_else: number}>
type EventD = DeviceEvent<"event_d", {some_elseNumber: number}>

type EventImInterestedIn = EventA | EventB | EventC

const test: Record<Partial<EventImInterestedIn["type"]>, (data: EventImInterestedIn["data"]) => void> = {
    event_a: ({some}) => {},
    event_b: ({some_other}) => {}
}

Playground
我如何才能做到这一点?
谢谢

vbkedwbf

vbkedwbf1#

如果你使用一个记录,你会失去type键和它的data之间的连接,所以每个回调属性中的data参数的类型将是所有data字段的并集,而不是对应于type的那个。
你可以通过像这样声明一个Map类型来避免这个问题:

type Events = {
  [E in EventImInterestedIn as E['type']]?: (data: E['data']) => void
}

它MapEventImInterestedIn联合成员,并使用每个type属性作为键(使用as的键重Map),并使用适当的data属性作为回调的参数。
如果使用Events作为test的类型,将推断出正确的回调参数类型:

const test: Events = {
    event_a: ({some}) => {},
    // (parameter) some: string
    event_b: ({some_other}) => {},
    // (parameter) some_other: string
    event_c: (e) => {}
    // (parameter) e: { some_else: number; }
}

TypeScript playground

相关问题