Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strict unions could be made simpler with a type helper #168

Open
hayes opened this issue Jul 2, 2019 · 0 comments
Open

Strict unions could be made simpler with a type helper #168

hayes opened this issue Jul 2, 2019 · 0 comments

Comments

@hayes
Copy link
Contributor

hayes commented Jul 2, 2019

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',
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant