Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript: Rename obj properties with typing

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
};
like image 603
iPherian Avatar asked Oct 04 '20 15:10

iPherian


1 Answers

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}

like image 151
Titian Cernicova-Dragomir Avatar answered Nov 04 '22 00:11

Titian Cernicova-Dragomir