Skip to content

proposal: Narrow Discriminated Unions by discarding types with no possible values #13300

Closed
@nahuel

Description

@nahuel

It will be nice if TS narrowed Discriminated Unions by discarding types with no possible values (e.g. {tag: 'a' & 'b', x : 1}).

Example:

type A = {tag: 'a', x: 1} 
type B = {tag: 'b', y: 1}
type TaggedAsB = {tag: 'b'}

type T = (B | A) & TaggedAsB  // {tag: 'a' & 'b', x: 1} | {tag: 'b', y: 1}

let o : T
o.y       // make legal, because the only possible values have type {tag: 'b', y: 1} 

Use case:

type Event = ({eventName : "EVENT_A", dataA : any} | 
              {eventName : "EVENT_B", dataB : any})

// define a callback for an specific event, with this new feature you can use a tag
// and the intersection type operator to select an specific case from the Event DU
function handlerEventA(event : Event & {eventName: "EVENT_A"}) {
      // with this new feature, here we don't need a runtime typeguard, 
      // TS already knows what specific DU case is event:
      let x = event.dataA 
}

This comes from the discussion at #13203

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions