Reputation: 1861
/* I have enum A & B at first */
enum A {
FOO = 'BAR',
GAR = 'ZAR'
}
enum B {
FOO = 'BAR'
}
/* Is there any way to retrieve something merged like this? */
enum Merged {
A_FOO = 'A_BAR',
A_GAR = 'A_ZAR',
B_FOO = 'B_BAR'
}
I have 2 enum
s and I cannot guarantee their keys are mutually exclusive. Also, I want to pre-process their values before merging as well.
May I know if there any way to achieve this?
Upvotes: 1
Views: 1398
Reputation: 9192
Constructing a type for this is possible, but not until TS 4.1, which gives us template literal types.
In TS 4.1 you can define a helper type Prefix
, which does the magic:
type Prefix<T extends { [K in keyof T]: string }, P extends string> = {
[K in keyof T & string as `${P}_${K}`]: `${P}_${T[K]}`
}
Then, it is straightforward to define a Merge
function which uses this type to construct a merged enum.
function merged<
T1 extends { [K in keyof T1]: string }, P1 extends string,
T2 extends { [K in keyof T2]: string }, P2 extends string,
>(obj1: T1, prefix1: P1, obj2: T2, prefix2: P2): Prefix<T1, P1> & Prefix<T2, P2> {
const result = {} as any; // Going to have to cast somewhere anyways...
for (const [k, v] of Object.entries(obj1)) {
result[`${prefix1}_${k}`] = `${prefix1}_${v}`;
}
for (const [k, v] of Object.entries(obj2)) {
result[`${prefix2}_${k}`] = `${prefix2}_${v}`;
}
return result;
}
const Merged = merged(A, 'A', B, 'B')
console.log(Merged) // { A_FOO: "A_BAR", A_GAR: "A_ZAR", B_FOO: "B_BAR" }
You can try this out on the TypeScript playground, or install typescript@next
in your project. TS 4.1 is planned to release on November 17th.
Upvotes: 2