Skip to content

Discriminated Union is not narrowed to never when all types are checked in default case if discriminator field is literal typeΒ #61207

@yavanosta

Description

@yavanosta

πŸ”Ž Search Terms

switch default discriminated Unions

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about discriminated unions

⏯ Playground Link

https://www.typescriptlang.org/play/?ts=5.7.3#code/KYOwrgtgBAgiCWECGAbAKgTwA7CgbwCgooBjJAFygF4oByM82gGiKgBMB7Ac2rs69oEAvgQLlsuOIlS9CxcTgBcUAAYASPFOToJAOgZCVAblYRgHAO7KAzuQBO8EFxNCoAH3ysFwZes0JtTBxdfkMTYgAjJDsAaxt7R2dhUQAzMBAScngOEFIAC2ASGIAKLGUQYAA3YDsASk95PLtLKAqLKABRO2a7YtounoBCWlrkgjSMrJyoJEzskGKkANRlLVR6uSgAei2oAGEOCCx4FGBrVngUqEXllF1vaioaNZ1ghg3WYhIc6w5T3RQ3Bu0juZkstXCUFcwBQ1lwl2uSxB9wkj2etyCwBC3A+xC+Pz+WMBXGB2l0UViENY0NhuE2XwKRVJ62pomIO32h2Op3OxGsFng5BIeURtxROFxeLIcNUGhemP0FEMik+UoJ-2JzNB5gsVLxeIidmASBikK+SBlfnlelCKhV+vxIF+GqBSLJFJieodhuNptVbGAKSQYBQ5HtDuFhRKbvWkJErA5ABEOGdWhxKN8jidgKx+YLhaLkd5JeaZda3hRw-rvk7CQDXWKwbqzQajSaW9LJBibdwq2ray6STG7h6vfqfe3-YHg6G+wyo1qIdtdgAeAC0a9gdi4kFAlA4VwetBetCg8GsacoFus8C4ICQEVOUHIHCgWGiSDM5BqUAPz9RtAVNUdiCMQIhCEAA

πŸ’» Code

enum AnimalType {
  cat = 'cat',
  dog = 'dog'
}

type Animal = {
  type: `${AnimalType.cat}`;
  meow: string;
} | {
  type: `${AnimalType.dog}`;
  bark: string;
}

function check(p: never) {
  throw new Error('Error!')
}

function action(animal: Animal) {
  // Compiles
  if (animal.type === AnimalType.cat) {
    console.log(animal.meow);
  } else if (animal.type === AnimalType.dog) {
    console.log(animal.bark);
  } else {
    check(animal)
  }

  // Compiles
  switch (animal.type) {
    case `${AnimalType.cat}`:
      console.log(animal.meow);
      break;
    case `${AnimalType.dog}`:
      console.log(animal.bark);
      break;
    default:
      check(animal);
  }

  // Does not compile
  switch (animal.type) {
    case AnimalType.cat:
      console.log(animal.meow);
      break;
    case AnimalType.dog:
      console.log(animal.bark);
      break;
    default:
      check(animal); // <-- Argument of type 'Animal' is not assignable to parameter of type 'never'
  }
}

πŸ™ Actual behavior

The last example does not compile

πŸ™‚ Expected behavior

To my understanding all three examples do exactly the same and all should compile.

Additional information about the issue

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions