Reputation: 6814
I have a function callback<T>
whose return value is either Promise<T>
or undefined
. Now I want to create a wrapping function that will execute the function and always returns a Promise - in case the callback function returned undefined
, the Promise should resolve with undefined
.
The code isn't the problem, but maintaining type inference in Typescript. How would the function signature have to look so that the typing is maintained?
(non-working) example:
function wrap<T>(callback: () => Promise<T> | undefined): Promise<T> | Promise<undefined>
// inferred signature should be Promise<undefined>
const a = wrap(() => undefined)
// inferred signature should be Promise<number>
const b = wrap(() => Promise.resolve(5))
Upvotes: 1
Views: 552
Reputation: 1074365
My first thought is a function overload:
function wrap<T>(callback: () => Promise<T>): Promise<T>;
function wrap(callback: () => undefined): Promise<undefined>;
function wrap<T>(callback: () => any): Promise<T | undefined> {
const result = callback();
if (typeof result === "undefined") {
return Promise.resolve(undefined);
}
return result;
}
That can also be expressed in a type if that's useful:
type Wrapper = {
<T>(callback: () => Promise<T>): Promise<T>;
(callback: () => undefined): Promise<undefined>;
}
const wrap: Wrapper = (callback: () => any) {
const result = callback();
if (typeof result === "undefined") {
return Promise.resolve(undefined);
}
return result;
};
Upvotes: 2