I have a helper function that takes an optional options
parameter. Based on the options provided, the return type should be determined.
This is the current implementation without the deduced return type. It will always return type Promise<void>
.
type Options = {
awaitExecution?: boolean;
returnResult?: boolean;
};
type MaybeAsyncFunction<T> = () => T | Promise<T>;
async function apiCall<ReturnType>(
executionHandler: MaybeAsyncFunction<ReturnType>,
options?: Options
) {
const { awaitExecution = true, returnResult = true } = options ?? {};
try {
if (awaitExecution) {
const result = await executionHandler();
if (returnResult) {
return result;
}
} else {
executionHandler();
}
} catch (err) {
/** error handling */
}
return;
}
The behavior I’m looking for is this: If nothing shall be returned, then the return type should be Promise<void>
. If a return is expected, then the return type should be the return type of the executionHandler (Promise<ReturnType>
).
The provided options (if any) in combination with the default values for the remaining options should serve to determine whether something should be returned or not.
const executionHandler = () => 'abc';
apiCall(executionHandler, errorHandler); // Should return Promise<string>
apiCall(executionHandler, errorHandler, { awaitExecution: true }) // Should return Promise<string>
apiCall(executionHandler, errorHandler, { awaitExecution: false }) // Should return Promise<void>
I am stuck and can’t find out how to implement this. I have found a few similar questions (1, 2, 3), but couldn’t quite work out the solution. My current solution still only returns Promise<void>
.
type ApiCallReturnType<T, O> = O extends undefined
? T
: O extends { awaitExecution: true; returnResult: true }
? T
: void;
async function apiCall<ReturnType, Opts extends Options = object>(
executionHandler: MaybeAsyncFunction<ReturnType>,
options?: Opts
): Promise<ApiCallReturnType<ReturnType, Opts>> {
/* try catch */
return Promise.resolve() as ApiCallReturnType<ReturnType, Opts>; // To return void
}
Here is a Playground