Búsqueda de sitios web

typescript - Inferencia de tipos de funciones de orden superior


Estoy intentando crear una clase Provider que almacene una función manejadora y que pueda ejecutarse con algún contexto:

interface ProviderHandler<A extends any[] = any[], R = any> {
  (this: RequestContext, ...args: A): R
}

type FlatPromise<T> = Promise<T extends Promise<infer E> ? E : T>

interface WrapCall {
  <T extends ProviderHandler>(provider: Provider<T>): T extends ProviderHandler<
    infer A,
    infer R
  >
    ? (...args: A) => FlatPromise<R>
    : never
}

interface RequestContext {
  /* ... */
  call: WrapCall
}

class Provider<T extends ProviderHandler = ProviderHandler> {
  handler: T

  constructor(options: { handler: T }) {
    this.handler = options.handler
  }
}

const context = { /* imagine it implemented */ } as RequestContext

Todo funciona bien si el manejador es una función simple:

const p1 = new Provider({
    async handler() {
        return 5
    }
})

// r1 = number
const r1 = await context.call(p1)()

Pero no funciona con manejadores genéricos:

const p2 = new Provider({
    async handler<T>(t: T) {
        return t
    }
})

// actual: r2 = unknown
// expected: r2 = string
const r2 = await context.call(p2)('text')

Enlace del parque

Temas relacionados:

  • https://github.com/microsoft/TypeScript/pull/30215
  • https://github.com/microsoft/TypeScript/issues/30134