I have some methods that use NonNullable<T> to allow certain parts to assume that null checks have been performed before being called. I also have a function that will perform that check before then calling aforementioned methods.
My problem is that this function accepts a generic T which I need to narrow down to NonNullable<T>. When writing guarding code that checks for null and undefined values, this type is not automatically narrowed down to a non-nullable type by means of inference.
export interface UrlParam<T> {
defaultValue: T,
encode: (value: NonNullable<T>) => string
decode: (value: string) => NonNullable<T>
}
interface LatLng {
lat: number
lng: number
}
const COORDINATE_DELIMITER = ','
const locationParam: UrlParam<LatLng | null> = {
defaultValue: null,
encode: ({ lat, lng }) => [lat, lng].join(COORDINATE_DELIMITER),
decode: value => {
const [lat, lng] = value.split(COORDINATE_DELIMITER)
return {
lat: Number(lat),
lng: Number(lng),
}
}
}
function encodeParam<T>(urlParam: UrlParam<T>, value: T) {
return value !== undefined && value !== null ? urlParam.encode(value) : null
}
The encodeParam function produces the following compilation error:
Argument of type 'T' is not assignable to parameter of type 'NonNullable'
I can resolve this by forcing the TypeScript compiler to treat T as NonNullable<T>:
urlParam.encode(value as NonNullable<T>)
However I am looking for a solution where the compiler can actually infer this type based on the condition itself. Is this possible? Am I perhaps approaching this the wrong way?