type-fest icon indicating copy to clipboard operation
type-fest copied to clipboard

Proposal: NonDiscriminatedUnion

Open RebeccaStevens opened this issue 2 years ago • 2 comments

For a union of only 2 elements, this would just be:

type NonDiscriminatedUnion<Union> = Union | UnionToIntersection<Union>

However, the type would be more complex for the case of 3 or more elements.

Example usage

Given these types:

type Foo =
  | {
      bar: number;
    }
  | {
      baz: string;
      qux?: number;
    };

type NonDiscriminatedFoo = NonDiscriminatedUnion<Foo>;

If you have a value typed as NonDiscriminatedFoo

declare const value: NonDiscriminatedFoo;

You can access each part of the union independently.

// No benefit over normal union.
if ('bar' in value) {
    // `value ` will be typed as `{ bar: number; }`
}

// No benefit over normal union.
if ('baz' in value) {
    // `value` will be typed as `{ baz: string; qux?: number; }`
}

// This benefits from the non-discriminated union
if ('bar' in value && 'baz' in value) {
    // `value` will be typed as `{ bar: number; baz: string; qux?: number; }`
    // `value` would be `never` with a normal union
}

Upvote & Fund

  • We're using Polar.sh so you can upvote and help fund this issue.
  • The funding will be given to active contributors.
  • Thank you in advance for helping prioritize & fund our backlog.
Fund with Polar

RebeccaStevens avatar Mar 30 '22 07:03 RebeccaStevens

I'm looking for this type too. I found a solution here and it's working fine but it's a lot of code. It will be great to have NonDiscriminatedUnion<T> or AllFields<T>

TkaczykAdam avatar May 03 '22 08:05 TkaczykAdam

Isn't this covered by UnionToIntersection?

JGJP avatar Jan 16 '24 06:01 JGJP