Búsqueda de sitios web

¿Cómo definir un tipo mapeado para los tipos de retorno de métodos en TypeScript 4.5.4?


En TypeScript 4.4.4 este código se compiló sin problemas:

/**
 * type to get only those properties that are functions
 */
type FunctionProperties<T> = {
  [P in keyof T]: T[P] extends (...args: any) => any ? P : never;
}[keyof T];

type ReturnTypeOfMethod<T, K extends FunctionProperties<T>> = ReturnType<T[K]>;

ver el ejemplo de Playground 4.4.4

Pero el mismo código no compila en TypeScript 4.5.4 - ver ejemplo en Playground 4.5.4

Type 'T[K]' does not satisfy the constraint '(...args: any) => any'.
  Type 'T[FunctionProperties<T>]' is not assignable to type '(...args: any) => any'.
    Type 'T[T[keyof T] extends (...args: any) => any ? keyof T : never]' is not assignable to type '(...args: any) => any'.
      Type 'T[keyof T]' is not assignable to type '(...args: any) => any'.
        Type 'T[string] | T[number] | T[symbol]' is not assignable to type '(...args: any) => any'.
          Type 'T[string]' is not assignable to type '(...args: any) => any'.

Lo extraño es que el tipo ReturnTypeNumber todavía muestra el tipo esperado (number en este ejemplo).
¿Alguna idea de por qué esto ya no funciona o cómo solucionarlo (usar @ts-ignore no es una solución)?

Respuesta #1

Bastante verboso ya que tienes que repetir la condición, pero suprimiría el error.

type ReturnTypeOfMethod<T, K extends FunctionProperties<T>> =
  T[K] extends (...args: any) => any ? ReturnType<T[K]> : never;

Respuesta #2

Resulta que este fue un cambio importante documentado en la versión 4.5:

Restricciones sobre la Asignabilidad a Tipos Condicionales TypeScript ya no permite que los tipos sean asignables a tipos condicionales que usan infer, o que sean distributivos. Hacerlo anteriormente a menudo causaba grandes problemas de rendimiento. Para más información, consulte el cambio específico en GitHub.

Así que realmente necesitamos la versión más detallada como se menciona en la respuesta de Stoneheart