I tried to write the following TypeScript code and the fact that it's kinda working is raising some questions. It's "kinda" working because the type of the constructed "union"
property is indeed the union of the record values. Record keys are ignored.
export type Unificator<T extends Record<string, unknown>> = { [P in keyof T as "union"]: T[P] }["union"];
let u: Unificator<{
a: { foo: "bar" },
b: { bar: "baz" },
c: { answer: 42 }
}>;
u = { foo: "bar" }; // Valid.
u = { bar: "baz" }; // Valid.
u = { answer: 42 }; // Valid.
The first three questions are:
- Is this a legitimate use of mapped types or am I doing something weird?
- Is there a more orthodox way to union an arbitrary number of types together?
- If the above code is indeed legit, is there a way to avoid that temporary "union" property?
But the most important question for me is another one:
- Is there a way to "intersect" an arbitrary number of types?
I want to do the following.
export type Intersector<T extends Record<string, unknown>> = /* HELP PLZ! */;
let i: Intersector<{
a: { foo: "bar" },
b: { bar: "baz" },
c: { answer: 42 }
}>;
i = {
foo: "bar",
bar: "baz",
answer: 42
}; // Valid.