What I want to do
I want to typing a javascript function below. This function remaps first argument's property names by second argument.
I use the remap function to create query string parameters.
For example, from { param1: 1, param2: 2, param3: 3} to ?p1=1&p2=2&p3=3.
/**
* @example
*
* const original = { a: 1, b: 'WOW', c: new Date(2019, 1, 1, 0, 0, 0) };
* const mapping = { a: 'hello', b: 'world', c: '!!!' };
*
* > remap(original, mapping);
* { hello: 1, world: 'WOW', '!!!': new Date(2019, 1, 1, 0, 0, 0) }
*/
const remap = (original, mapping) => {
const remapped = {};
Object.keys(original).forEach(k => {
remapped[mapping[k]] = original[k];
});
return remapped;
};
My unsound code
I tried a code below, but this is unsound.
export const remap = <
T extends { [key: string]: any },
U extends { [P in keyof T]: string }
>(original: T, mapping: U) => {
const remapped: any = {};
Object.keys(original).forEach(k => {
remapped[mapping[k]] = original[k];
});
// Problems
// 1. remapped is declared as any, and cast required.
// 2. All values are declared ad any.
return remapped as { [P in keyof U]: any };
};
const remapped = remap(
{ a: 1, b: 'text', c: new Date() },
{ a: 'Hello', b: 'World', c: '!!!' }
);
console.info(remapped);
remapfunction for?