В настоящее время условные типы имеют странную связь с типами возвращаемых функций, но в вашем случае вы можете сделать небольшую хитрость с перегрузкой, имеющей максимально широкий тип, а также обрабатывать крайние случаи вокруг известных null
и undefined
передается в функцию:
function mapOptional<I = any, R = unknown>(input: null, callback: (value: I) => R): null
function mapOptional<I = any, R = unknown>(input: undefined, callback: (value: I) => R): undefined
function mapOptional<I, R>(input: I, callback: (value: NonNullable<I>) => R)
: I extends (undefined | null) ? I : R
function mapOptional<I, R>(input: I, callback: (value: I) => R) {
if (input === null) {
return null;
}
if (input === undefined) {
return undefined;
}
return callback(input);
}
mapOptional(undefined, x => x.toFixed()) // type is undefined
mapOptional(null, x => x + 5) // type is null
mapOptional(56, x => x + 5).toFixed() // works
declare const optionalNumber: number | undefined
const r = mapOptional(optionalNumber, x => x + 5) // undefined | number
if (r) {
console.log(r.toFixed())
}