I have a function like
const toString = (date?: Date) => date?.toString();
Which I would like typecheck to (Date) => string
when given a Date
but to (Date | undefined) => string | undefined
when given Date | undefined
or undefined.
I have tried something like this in a number of different ways:
type Verify<T, D> = T extends undefined ? D | undefined : D;
const dateToString = <T extends Date | undefined>(date: Verify<T, Date>) => {
if (date === undefined) {
return undefined as Verify<T, string>;
}
return date.toString() as Verify<T, string>;
};
const a = dateToString(new Date(23));
const b = dateToString(undefined as Date | undefined);
const c = dateToString(undefined);
But I cannot seem to get the behavior I want, either everything typechecks to (Date | undefined) => string
or (Date) => string
. Apparently I do not grok typescript generics with constraints.
A proper name for this helper constraining type would also be appreciated.
CodePudding user response:
How about using a function overload...
function dateToString(date: Date): string;
function dateToString(date?: Date): string | undefined ;
function dateToString(date?: Date): string | undefined {
if (date === undefined) {
return undefined;
}
return date.toString();
}
const x = dateToString(new Date()); // x: string
const y = dateToString(); // y: string | undefined
CodePudding user response:
type Verify<T, D> = T extends undefined ? D | undefined : D;
const dateToString = <T extends Date | undefined>(date: T): Verify<T, string> => {
if (date === undefined) {
return undefined as Verify<T, string>;
}
return date.toString();
};
const a = dateToString(new Date()); // const a: string
const b = dateToString(undefined as Date | undefined); // const b: string | undefined
const c = dateToString(undefined); // const c: string | undefined