In the following snippet, how can I define subscribe
such that given a specific event name (e.g. "NamedEvent") the callback argument, event
, has a correctly inferred Event
type?
type EventName = "NamedEvent" | "OtherEvent";
type Event = {
name: "NamedEvent",
data: { a: number, b: string }
} | {
name: "OtherEvent",
data: { c: string, d: number }
}
subscribe("NamedEvent", (event) => {
...
});
Ideally in the callback, Typescript would infer that the event provided is specifically the one with the matching name, "NamedEvent", and cannot be any other one. I've tried to implement this several times with no luck.
CodePudding user response:
I tried your example and Typescript behaves exactly as it should:
You don't even need type EventName
as this information is redundant.
CodePudding user response:
I discovered the Extract<Type, Union>
utility type today, so this is more or less what I came up with:
const subscribe<N extends Event['name']>(
eventName: N,
callback: (event: Extract<Event, { name: N }>) => void
) => {
// business logic...
callback(event)
}
From the Typescript documentation here:
Constructs a type by extracting from
Type
all union members that are assignable toUnion
.