I have this type
type Test = {
checked: boolean;
selection: 'female' | 'male'
}
And, I would like to transform it into another type such as
type Test = {
checked: Record<string, boolean>;
selection: Record<string, 'female' | 'male'>
}
Then, I wrote this transform
type NestedTest<T> = T extends object
? { [P in keyof T]: NestedTest<T[P]> }
: Record<string, T>;
But, when I call it like
type Test2 = NestedTest<Test>;
Then I got the unexpected results below
type Test2 = {
checked: Record<string, false> | Record<string, true>;
selection: Record<string, "female"> | Record<string, "male">;
}
As you can see, typescript auto splits these union types into a union of Record
type instead of only one.
I don't why it is like that. If you can, please tell me what I misunderstood? and how to fix it.
Here is my playground
Thank you so much!
CodePudding user response:
You basically need to stop the unions from distributing to seperate Record
s. See Distributive Conditional Types in the TypeScript docs.
type NestedTest<T> = [T] extends [object]
? { [P in keyof T]: NestedTest<T[P]> }
: Record<string, T>;
If we surround T
and object
with square brackets, the elements of the union will not be distributed to different Records.