Strict unions could be made simpler with a type helper
Opened this issue · 0 comments
hayes commented
I'm not sure what this projects stance is on type helpers, but the output for strict unions is pretty verbose.
I am working on a project where we create interfaces very similar to the ones used by this project for strict unions. Our approach uses a type helper to create much smaller output for complex unions.
I'm not sure if this would be a good idea to adopt here, but thought I would share it in case you think it's useful:
We use the following type helpers:
export type UnionObject<T extends {}, Undefined = undefined> = {
[K in keyof T]: Pick<T, K> & { [J in Exclude<keyof T, K>]?: Undefined }
}[keyof T];
export type UnionObjectWithType<T extends {}, Undefined = undefined> = {
[K in keyof T]: Pick<T, K> & { [J in Exclude<keyof T, K>]?: Undefined } & { __type: K }
}[keyof T];
which could be used like:
type MyUnion = UnionObject<{
foo: number;
bar: string;
}>;
type MyUnionWithType = UnionObjectWithType<{
foo: number;
bar: string;
}>;
const x: MyUnion = {
bar: '1232',
};
const y: MyUnion = {
foo: 1232,
bar: undefined,
};
const z: MyUnionWithType = {
__type: 'foo',
foo: 1232,
bar: undefined,
};
/*
Type '{ foo: number; bar: string; }' is not assignable to type '(Pick<{ foo: number; bar: string; }, "foo"> & { bar?: undefined; }) | (Pick<{ foo: number; bar: string; }, "bar"> & { foo?: undefined; })'.
Type '{ foo: number; bar: string; }' is not assignable to type 'Pick<{ foo: number; bar: string; }, "bar"> & { foo?: undefined; }'.
Type '{ foo: number; bar: string; }' is not assignable to type '{ foo?: undefined; }'.
Types of property 'foo' are incompatible.
Type 'number' is not assignable to type 'undefined'.ts(2322)
*/
const error: MyUnion = {
foo: 1232,
bar: 'asd',
};