DEV Community

Discussion on: Why does typescript not conditionally pick the right type in a union?

Collapse
 
thibmaek profile image
Thibault Maekelbergh

OK, I realized it shortly after posting. However, how would you ever handle a typical case like a state reducer (in Redux for example) where your payloads can contain different subsets of data but they occur via events?

interface PayloadA {
  propA: string;
}

interface PayloadB {
  propB: number;
}

interface Action = {
  type: string;
  payload: PayloadA | PayloadB;
}

function reducer(state = {}, action: Action) {
  switch(action.type) {
    case 'ADD':
       return { state, action.payload.propA }
    case 'UPDATE':
      return { state, action.payload.propB }
    default: return state;
  }
}

TS always warns that propB would not be available in type ADD being dispatched and propA not being available in UPDATE being dispatched.

Collapse
 
macsikora profile image
Pragmatic Maciej

So the proper typying of this case is:

interface PayloadA {
  type: 'ADD';
  propA: string;
}

interface PayloadB {
  type: 'UPDATE';
  propB: number;
}

type Action = PayloadA | PayloadB 

We need to join type with prop, in other way TS is not able to understand what property is in add action or update action. Such construct is known as sum type or discriminated union.

Thread Thread
 
thibmaek profile image
Thibault Maekelbergh

Thanks, I'll try this