Búsqueda de sitios web

Interfaz de función genérica de Typescript en otra interfaz


Tengo una interfaz genérica

export interface Method<T> {
    (answer: T): T;
}

Quiero crear una interfaz donde tenga la función fn

interface Wrapper {
    fn: <T,>(a: T ) => T
}

pero en lugar de escribir manualmente el tipo de función, quiero usar la interfaz

interface MethodWrapper {
   fn: Method
}

Quiero que la fn sea genérica a nivel de fn y no a nivel de la interfaz. ¿Es posible?

enlace de ts-playground

Respuesta #1

El sistema de tipos de TypeScript carece de la expresividad para transformar programáticamente Method<T> en Wrapper. Sería necesario mover el alcance del parámetro de tipo genérico T de maneras que no se pueden hacer.

Si TypeScript tuviera valores genéricos como se solicita en microsoft/TypeScript#17574, entonces podrías decir algo como:

// Invalid TypeScript, don't do this
interface Wrapper {
  fn: forall T. Method<T>;
}

o

// Invalid TypeScript, don't do this
interface Wrapper {
  fn: <T> Method<T>;
}

Pero no lo hace, así que no podemos.


Casi puedes hacerlo al revés y definir Method<T> en términos de Wrapper, usando expresiones de instanciación. Digo "casi" porque requiere que bajes al nivel de tipos y adquieras (o finjas adquirir) un valor wrapper de tipo Wrapper antes de volver a elevarte al nivel de tipos. Así:

declare const wrapper: Wrapper; // pretend to have this

type Method<T> = typeof wrapper.fn<T> // instantiate fn with <T>
// type Method<T> = (a: T) => T

Dependiendo de tu caso de uso, eso puede o no ser útil.

Enlace de Playground al código

Respuesta #2

No estoy seguro de entender completamente tu pregunta, pero adivinando por tu playground de TS, necesitas pasar el tipo del genérico:

interface MethodWrapper {
   fn: Method<T> // T should be the type you want fn to receive
}