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:
keyse refiere al nombre de una propiedad,T[key]se refiere a la propiedad llamadakeyen el tipoT.
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.
