Why is it that Typescript cannot discriminate a type union whose types are from the return types of function, without explicitly declaring the return type on the function?
Here I do not specify the return values of the event creator functions and the union type cannot be narrowed.
enum EventType {
FOO = "foo",
GOO = "goo",
}
function createFooEvent(args: {
documentId: number | null
}) {
return {
type: EventType.FOO,
data: args
}
}
function createGooEvent(args: {
id: number
isSelected: boolean
}) {
return {
type: EventType.GOO,
data: args
}
}
type EventArgType =
| ReturnType<typeof createFooEvent>
| ReturnType<typeof createGooEvent>
function eventHandler(event: EventArgType) {
switch(event.type) {
case EventType.FOO: {
// Note that `event` contains `data` but `data`'s type is a union and has not been discriminated
event.data;
break
}
}
}
But if I specify the return types as follows then the union can be discriminated.
function createFooEvent(args: {
documentId: number | null
}): {
type: EventType.FOO,
data: {
documentId: number | null
}} {
return {
type: EventType.FOO,
data: args
}
}
function createGooEvent(args: {
id: number
isSelected: boolean
}): {
type: EventType.GOO,
data: {
id: number
isSelected: boolean
}} {
return {
type: EventType.GOO,
data: args
}
}