The following sample code does not pass the type check. I would like to find a way to make it pass without as casting, if possible.
type SupportedHandlerType = string | number | Date
type Handler<T> = (data: T[]) => void
function example<T extends SupportedHandlerType>(data: T[]) {
const handler = getHandler(data)
handler(data)
}
function stringHandler(data: string[]) {
}
function numberHandler(data: number[]) {
}
function dateHandler(data: Date[]) {
}
function getHandler<T>(data: T[]): Handler<T> {
const first = data[0]
if (typeof first == 'string') {
return stringHandler // Type 'T' is not assignable to type 'string'
}
if (typeof first == 'number') {
return numberHandler // another error here
}
return dateHandler // and here
}
My real life version is much more complicated, but this simple piece show cases the problem I have: I have a few types forming a union (SupportedHandlerType), and the generic function is called with one of those. I have a getHandler(), which dynamically looks at the types to determine which one it is and returns the appropriate handler function, which has a dedicated type instead of T.
Is there a way to somehow narrow the types so that I don't get errors such as Type 'T' is not assignable to type 'string'?