Búsqueda de sitios web

Genérico de TypeScript para cambiar todos los tipos de un tipo en particular a otro


Estoy intentando crear un tipo en TypeScript que tome un objeto y convierta todas las claves de tipo number en string. Lo siguiente no funciona:

export type ChangeTypeOfKeys<T extends object> = {
  [key in keyof T]: key extends number ? string : T[key]
}

const c: ChangeTypeOfKeys<{ a: number, b: boolean }> = {
    a: 'ok',
    b: false,
}

El tipo resultante debería ser { a: string, b: boolean }, pero en su lugar obtengo un error de TS:

Type 'string' is not assignable to type 'number'.(2322)
input.tsx(5, 29): The expected type comes from property 'a' which is declared here on type 'ChangeTypeOfKeys<{ a: number; b: boolean; }>'

Enlace del playground de TS

Creo que el problema está relacionado con cómo estoy usando key en key in keyof T, ya que reemplazar key extends number con otro argumento funciona:

export type ChangeTypeOfKeys<T extends object, Replace> = {
  [key in keyof T]: Replace extends number ? string : T[key]
}

const c: ChangeTypeOfKeys<{ a: number, b: boolean }, number> = {
    a: 'ok',
    b: 'ok',
}

Enlace del playground de TS

No estoy seguro si hay alguna propiedad especial con key que me esté perdiendo aquí. ¡Gracias de antemano!

Respuesta #1

Para obtener el valor de la propiedad referenciada por key, haz esto:

export type ChangeTypeOfKeys<T extends object> = {
  [key in keyof T]: T[key] extends number ? string : T[key]
  //                ^^^^^^
}

Enlace del parque


El tipo de key siempre será string en el ejemplo que diste. Para ser absolutamente claro, en tu código:

  • key se refiere al nombre de una propiedad,
  • T[key] se refiere a la propiedad llamada key en el tipo T.

También tenga en cuenta que extends object permite tipos [] (entre otros), lo cual podría no ser lo que desea. Intente extender de {} o Record<string, any> en su lugar.

Artículos relacionados