1

Code

Imagine an interface with two function overloads.

interface Api {
  parseNumber(input: string, useBigInt: true): bigint
  parseNumber(input: string, useBigInt: false): number
}

How can you map over these functions to create a new interface with async versions of each function?

{
  parseNumber(input: string, useBigInt: true): Promise<bigint>
  parseNumber(input: string, useBigInt: false): Promise<number>
}

What I tried

You can easily pull out a union of function names, a union of the function signatures, but when you ask for a union of the return types you only get the last one in declaration order.

type TMethodNames = keyof Api; // GOOD: `parseNumber`
type TMethodImplementations = Api[keyof Api]; // GOOD: both signatures
type TMethodReturns = ReturnType<TMethodImplementations> // BAD: only `number` rather than `number | bigint`

Trying to produce a new interface via mapping results in all but the last function signature being dropped.

type AsyncApi = {
  [TMethodName in keyof Api]: (...args: Parameters<Api[TMethodName]>) => Promise<ReturnType<Api[TMethodName]>>
};

const asyncApi = null as unknown as AsyncApi;
asyncApi.parseNumber('123', false); // GOOD: return type is `Promise<number>`
asyncApi.parseNumber('123', true); // BAD: signature is completely missing
steveluscher
  • 4,144
  • 24
  • 42
  • It's unfortunately a missing feature; see [ms/TS#29732](https://github.com/microsoft/TypeScript/issues/29732) and the answers to the linked questions for possible approaches; nothing great here, though. – jcalz Mar 22 '23 at 19:37
  • Noooooooo! Ugh. I need this badly, to be able to finish up an API I'm working on. :( – steveluscher Mar 22 '23 at 20:47

0 Answers0