Search code examples
javascripttypescript

The default parameter breaks the auto typescript type selection


When i give a function a default value the types behave in an unobvious way.

type TRadio = {
  type: 'RADIO'
  value: string
}

type TChecks = {
  type: 'CHECK'
  value: string[]
}

type TGroup = TRadio | TChecks

const testFunc = ({ type, value }: TGroup) => {
  if (type === 'CHECK') value // string[] 👍
  if (type === 'RADIO') value // string 👍
}

const testFunc2 = ({ type = 'RADIO', value }: TGroup) => {
  if (type === 'CHECK') value // string | string[] 🤔
  if (type === 'RADIO') value // string | string[] 🤔
} 

Why testFunc2 with type = 'RADIO' breaks type of "value"?

I expected that the default value would not change the type selection logic and the functions would work the same


Solution

  • Seems TS keeps correlation between destructured variables until they are mutated. Assigning a default value is treated as potential mutation so the correlation is broken.

    Btw your default value doesn't make sense since type is required. So make it optional for the radio only.

    So you either don't mutate or mutate before destructuring:

    Playground

    type TRadio = {
      type?: 'RADIO'
      value: string
    }
    
    type TChecks = {
      type: 'CHECK'
      value: string[]
    }
    
    type TGroup = TRadio | TChecks
    
    const testFunc2 = ({ type, value }: TGroup) => {
      if (type === 'CHECK') value // string[] 🤔
      if (!type || type === 'RADIO') value // string 🤔
    } 
    
    const testFunc3 = (group: TGroup) => {
      group.type ??= 'RADIO';
      const {type, value} = group;
      if (type === 'CHECK') value // string[] 🤔
      if (type === 'RADIO') value // string 🤔
    }