javascript - Objeto con claves genéricas en typescript
Me gustaría crear una función común que tome un objeto, luego haga algunas transformaciones y devuelva un nuevo objeto con las mismas claves y valores diferentes. Estoy tratando de que sea "fuertemente tipada", así que todos los que la usen tendrán los beneficios de TS y las claves que no existan deberían generar un error.
Lo que tengo por ahora:
const hash = {
"first": 1,
"second": 2,
"third": 3,
}
type Mapper<T> = {
[key in keyof T]: number
}
type Result<T>= {
[key in keyof T]: () => number
}
const transform = <T>(mapper: Mapper<T>) => {
const result = {} as Result<T>
(Object.keys(mapper) as (keyof T)[]).map(key => {
result[key] = () => mapper[key]
})
return result
}
type Hash = typeof hash
const a = transform<Hash>(hash)
a.first()
// a.fifth() OK error
Funciona bien, pero estoy buscando soluciones para resolver esto:
Eliminar la afirmación de tipo
const result={} as Result<T>Elimina la afirmación de tipo
(Object.keys(mapper) as (keyof T)[])(o usaObject.entries, pero parece que en este caso también requiere afirmación de tipo)
¿Podría implementar lo mismo, pero de una manera más "limpia" en Typescript?
Respuesta #1
Object.keys devuelve siempre string[], por lo tanto necesitarás la conversión de tipo.
Una versión más pequeña y robusta usaría Object.fromEntries. Otra pequeña mejora sería usar el tipo de la clave original, con T[Key].
const hash = {
"first": "someString",
"second": 2,
"third": 3,
};
type Result<T>= {
[Key in keyof T]: () => T[Key]
};
const transform = <T extends object>(obj: T): Result<T> => {
return Object.fromEntries(
Object.keys(obj).map(
(key) => [key, () => obj[key as keyof T]]
)
) as Result<T>;
}
const a = transform(hash);
const first = a.first(); // returns "string"
// ^? const first: string
const second = a.second(); // return "number"
// ^? const second: number
Enlace del parque
