Skip to content

typescript/switch-exhaustiveness-check Pedantic ​

đź’­ This rule requires type information.
đźš§ An auto-fix is still under development.

What it does ​

This rule requires switch statements to be exhaustive when switching on union types.

Why is this bad? ​

When switching on a union type, it's important to handle all possible cases to avoid runtime errors. TypeScript can help ensure exhaustiveness, but only if the switch statement is properly structured with a default case that TypeScript can analyze.

Examples ​

Examples of incorrect code for this rule:

ts
type Status = "pending" | "approved" | "rejected";

function handleStatus(status: Status) {
  switch (status) {
    case "pending":
      return "Waiting for approval";
    case "approved":
      return "Request approved";
      // Missing 'rejected' case
  }
}

enum Color {
  Red,
  Green,
  Blue,
}

function getColorName(color: Color) {
  switch (color) {
    case Color.Red:
      return "red";
    case Color.Green:
      return "green";
      // Missing Color.Blue case
  }
}

Examples of correct code for this rule:

ts
type Status = "pending" | "approved" | "rejected";

function handleStatus(status: Status) {
  switch (status) {
    case "pending":
      return "Waiting for approval";
    case "approved":
      return "Request approved";
    case "rejected":
      return "Request rejected";
  }
}

// Or with default case for exhaustiveness checking
function handleStatusWithDefault(status: Status) {
  switch (status) {
    case "pending":
      return "Waiting for approval";
    case "approved":
      return "Request approved";
    case "rejected":
      return "Request rejected";
    default:
      const _exhaustiveCheck: never = status;
      return _exhaustiveCheck;
  }
}

enum Color {
  Red,
  Green,
  Blue,
}

function getColorName(color: Color) {
  switch (color) {
    case Color.Red:
      return "red";
    case Color.Green:
      return "green";
    case Color.Blue:
      return "blue";
    default:
      const _exhaustiveCheck: never = color;
      return _exhaustiveCheck;
  }
}

Configuration ​

This rule accepts a configuration object with the following properties:

allowDefaultCaseForExhaustiveSwitch ​

type: boolean

default: false

Whether to allow default cases on switches that are not exhaustive. When false, requires exhaustive switch statements without default cases.

allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing ​

type: boolean

default: false

Whether to allow this rule to run without strictNullChecks enabled. This is not recommended as the rule may produce incorrect results.

defaultCaseCommentPattern ​

type: [ string, null ]

Regular expression pattern that when matched in a default case comment, will suppress the exhaustiveness check. Example: "@skip-exhaustive-check" to allow default: // @skip-exhaustive-check

requireDefaultForNonUnion ​

type: boolean

default: false

Whether to require default cases on switches over union types that are not exhaustive. When true, switches with non-exhaustive union types must have a default case.

How to use ​

To enable this rule in the CLI or using the config file, you can use:

bash
oxlint --type-aware --deny typescript/switch-exhaustiveness-check
json
{
  "rules": {
    "typescript/switch-exhaustiveness-check": "error"
  }
}

References ​

Released under the MIT License.