I want to convert my typescript object keys to upper case, I want to know a good way to turn this?
var obj = {key1: value1,key2: value2}; into:
var obj = {KEY1: value1,KEY2: value2};
Can anyone suggest a better method without multiple looping and all?
CodePudding user response:
x = {}
Object.entries(obj).forEach(([k, v]) => {x[k.toUpperCase()] = v})
obj = x
CodePudding user response:
The most complicated part of this would be the typesafety as the Javascript is pretty straight forward.
All we need to do is isolate the keys/types we need to build out the "uppercased" copy of the object.
// All string-type keys in the object, and then uppercased
type UppercaseStringKeys<T> = Uppercase<Extract<keyof T, string>>;
// All non-string-type keys in the object type T
type NonStringKeys<T> = Exclude<keyof T, string>;
// Union of the above types
type NonStringAndUppercaseStringKeys<T> = NonStringKeys<T> | UppercaseStringKeys<T>;
// An object consisting of the above keys with the same values from the original object
type UppercaseObjectKeys<T extends { [key: string | number | symbol]: any }> = {
[x in UppercaseStringKeys<T>]: x extends string ? T[Lowercase<x>] : T[x];
};
We can obviously make this shorter - the above is purely for readability
type UppercaseObjectKeys<T extends { [key: string | number | symbol]: any }> = {
[x in Uppercase<Extract<keyof T, string>> | Exclude<keyof T, string>]: x extends string ? T[Lowercase<x>] : T[x];
};
Now all we need to do is do the Typescript mapping.
function uppercaseObjectKeys<T extends Record<any, any>>(existingObject: T) {
return Object.keys(existingObject).reduce((acc,key) => {
const newKey = `${key}`.toUpperCase() as keyof UppercaseObjectKeys<T>;
acc[newKey] = existingObject[key];
return acc;
}, {} as UppercaseObjectKeys<T>);
}
That's also fairly straight forward, we just return a new object with the "uppercased" keys.
We could edit the original object, but that's not the crux of this questions.
Then using the above function is straight forward, it should return us the new object with all string-type keys uppercased.
const x = {
foo: {},
bar: 1,
bazz_bazz: 'some string',
1: 2,
};
const y = uppercaseObjectKeys(x);
console.log(x);
/** {
"1": 2,
"foo": {},
"bar": 1,
"bazz_bazz": "some string"
} */
console.log(y);
/** {
"1": 2,
"FOO": {},
"BAR": 1,
"BAZZ_BAZZ": "some string"
} */
// works
y[1];
// wont work
y[2];