A little utility func (js) I use sometimes, and I'd love the typing to work like so:
// original js untypified
function prefixProperties(obj, prefix) {
let out = {};
for (let propt in obj) {
out[prefix + propt] = obj[propt];
}
return out;
}
let x : { num: number, date: Date } = { ... };
let y = prefixProperties(x, 'old');
/*
be great if typeof y was:
{
oldnum: number,
olddate: Date,
};
*/
Or whatever is the most specific is for such a function.
I thought about tuple maps but I guess they don't let you change the name of the key.
{
[K in keyof T]: whatever
};
You are in luck. While this is not possible in the current version of typescript, it soon will be. Typescript 4.1 (to be released in November 2020) will add support for Template literal types and mapped type 'as' clauses. With this new feature you can write:
type PrefixAll<T, P extends string> = {
[K in keyof T & string as `${P}${K}`]: T[K]
}
function prefixProperties<T, P extends string>(obj: T, prefix: P): PrefixAll<T, P> {
let out = {} as Record<string, unknown>;
for (let propt in obj) {
out[prefix + propt] = obj[propt];
}
return out as PrefixAll<T, P>;
}
let x : { num: number, date: Date } = { ... };
let y = prefixProperties(x, 'old');
y.olddate
y.oldnum
Playground Link
The part that is not currently possible is the as `${P}${K}`
. This part will will use template literal types to concatenate P
(the prefix) to the current property K
, and the as
clause will make the result of this concatenation the new property in the resulting object instead of K
You could even capitalize the prop name to get oldName
, oldDate
which is nicer in my opinion:
type PrefixAll<T, P extends string> = {
[K in keyof T & string as `${P}${Capitalize<K>}`]: T[K]
}
Playground Link
NOTE: I changed to prefix, instead of suffix as that is the transformation you specified at the end, but suffix would be just as simple just change the template literal type to ${K}${P}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With