D
Deno

help

Typescript Conditional Type Returns

Yybabts7/7/2023
I don't know why but this conditional type return is just causing me grief.
type InnerType<T> = T extends Promise<infer U> ? U : never;

export function CaptureErr<
F extends (...args: any[]) => any,
N extends string,
R extends ReturnType<F>,
>(
name: N,
fn: F,
message?: string,
): R extends Promise<any> ? Promise<InnerType<R> | Err<N>> : R | Err<N> {
try {
const result = fn();
if (result instanceof Promise) {
// Type 'Promise<Err<N> | InnerType<R>>' is not assignable to type
// 'R extends Promise<any> ? Promise<InnerType<R> | Err<N>> : R | Err<N>'.
return result.catch((e: Error) => {
e.cause = new Err(name ?? e.name, message ?? e.message);
return Promise.resolve(e as Err<N>);
}) as Promise<InnerType<R> | Err<N>>;
}
return result;
} catch (error) {
error.cause = new Err(name ?? error.name, message ?? error.message);
return error;
}
}
type InnerType<T> = T extends Promise<infer U> ? U : never;

export function CaptureErr<
F extends (...args: any[]) => any,
N extends string,
R extends ReturnType<F>,
>(
name: N,
fn: F,
message?: string,
): R extends Promise<any> ? Promise<InnerType<R> | Err<N>> : R | Err<N> {
try {
const result = fn();
if (result instanceof Promise) {
// Type 'Promise<Err<N> | InnerType<R>>' is not assignable to type
// 'R extends Promise<any> ? Promise<InnerType<R> | Err<N>> : R | Err<N>'.
return result.catch((e: Error) => {
e.cause = new Err(name ?? e.name, message ?? e.message);
return Promise.resolve(e as Err<N>);
}) as Promise<InnerType<R> | Err<N>>;
}
return result;
} catch (error) {
error.cause = new Err(name ?? error.name, message ?? error.message);
return error;
}
}
I suppose I could do this
return result.catch((e: Error) => {
e.cause = new Err(name ?? e.name, message ?? e.message);
return Promise.resolve(e as Err<N>);
}) as any;
// ^ BEGONE TYPE ERRORS!
return result.catch((e: Error) => {
e.cause = new Err(name ?? e.name, message ?? e.message);
return Promise.resolve(e as Err<N>);
}) as any;
// ^ BEGONE TYPE ERRORS!

Looking for more? Join the community!