I have types like this:
export type NotificationType = 'comment' | 'like' | 'message' | 'follow' | unknown
type MessageBody<T extends NotificationType> = T extends 'comment'
? {
body: string
threadId: string
projectId: string
}
: T extends 'like'
? {
resourceId: string
resourceType: 'project' | 'projectVersion' | 'thread' | 'comment'
}
: T extends 'message'
? {
body: string
chatId: string
}
: T extends 'follow'
? {}
: never
export type Message<T extends NotificationType = unknown> = {
channel: string
message: MessageBody<T> & {
type: T
}
timetoken: string | number
uuid?: string
publisher?: string
}
What I want to do now is infer the type of T by checking the property message.type without having to specify the type of T beforehand, so something like this:
function checkMessage(message: Message) { // No generic type given
switch (message.message.type) {
case 'comment':
message.message.body // infers to MessageBody<'comment'>
}
}
But with this approach I get an error on the switch statement with:
Property 'type' does not exist on type 'never'.
Which probably comes from the usage of unknown inside the NotificationType. How can I have the generic optional and still infer the type by checking the string?