Let's make the example even easier.
function convertDate<T extends string | undefined>(isoDate?: string): T {
return undefined
}
'undefined' is assignable to the constraint of type 'T'
Means: What you return in the function (undefined
), matches the constraints of your generic type parameter T (extends string | undefined)
.
, but 'T' could be instantiated with a different subtype of constraint 'string | undefined'.
Means: TypeScript does not consider that as safe. What if you defined your function like this at compile time:
// expects string return type according to generics
// but you return undefined in function body
const res = convertDate<string>("2019-08-16T16:48:33Z")
Then according to your signature, you expect the return type to be string. But at runtime that is not the case! This discrepancy that T can be instantiated with a different subtype (here string
) than you return in the function (undefined
) is expressed with the TypeScript error.
Possible solutions:
The only way to convince the compiler is to hard cast the return type:
declare function formatISODate(d: string): string
function convertDate<T extends string | undefined>(isoDate?: string): T {
return (isoDate ? formatISODate(isoDate) : undefined) as T
}
But I am not sure, if you really want that. The generic type parameter is pretty useless the way you define it in your function, as it not used in your parameters. Why not just write
function convertDate(isoDate?: string): string | undefined {
return isoDate ? formatISODate(isoDate) : undefined;
}
If your goal is just to avoid the repeating of the same ternary expression, you could achieve that with above code.
formatISODate
have a type parameter? If not I'm not sure what the T buys you. This function should just return the return value of formatISODate | undefined – Reid Evansstring | undefined
will show a type error when usingdate1: convertDate(date1)
, if date1 is stricly a string. – kk-dev11