I can't use TypeScript to evaluate the conditional when S is generic, so it ends up unifying both branches.
Is this a fundamental TS limitation, or is there a pattern to make this work without casts at the generic call site?
// I have a function that wraps execution in Result<T, E>
// It should also "passthrough" if the fn already returns Result (no double-wrap)
type UnwrapResult<T, E> = T extends Result<infer U, E> ? U : T;
function exception2Result<T, E extends Error = Error>(
fn: () => Promise<T>
): Promise<Result<UnwrapResult<T, E>, E>>;
const r = exception2Result(() => Promise.resolve(Result.Ok(123)));
async function request<S>(): Promise<Result<S>> {
return exception2Result(() => fetch("/api").then(r => r.json() as S));
// type-error without the cast
}
The Playground lets you write TypeScript or JavaScript online in a safe and sharable way.