Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript 4.6 sometimes treats tuple union types as "never" when switch-case has a "default" clause #47857

Closed
ide opened this issue Feb 12, 2022 · 2 comments Β· Fixed by #47927
Closed
Assignees
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue

Comments

@ide
Copy link

ide commented Feb 12, 2022

Bug Report

The error described below started with TypeScript 4.6.1-rc. A minimal repro is included.

πŸ”Ž Search Terms

  • Destructuring
  • Union types

πŸ•— Version & Regression Information

  • This changed between versions 4.5.5 and 4.6.1-rc

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

See this toy NAND evaluator. Something about the recursive union type causes TS to fail when destructuring the array. Deleting the default clause causes the error to go away. (The default clause is unnecessary if assuming TS is sound but one can see why a safety net is helpful.)

export type Expression = BooleanLogicExpression | 'true' | 'false';
export type BooleanLogicExpression = ['and', ...Expression[]] | ['not', Expression];

export function evaluate(expression: Expression): boolean {
  if (Array.isArray(expression)) {
    const [operator, ...operands] = expression;
    switch (operator) {
      case 'and': {
        return operands.every((child) => evaluate(child));
      }
      case 'not': {
        return !evaluate(operands[0]);
      }
      default: {
        throw new Error(`${operator} is not a supported operator`);
      }
    }
  } else {
    return expression === 'true';
  }
}

πŸ™ Actual behavior

The line const [operator, ...operands] = expression; produces the error: TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator.

πŸ™‚ Expected behavior

Expected there not to be an TS error.

@ide ide changed the title TypeScript 4.6 sometimes treats tuple union types as "never" TypeScript 4.6 sometimes treats tuple union types as "never" when switch-case has a "default" clause Feb 12, 2022
@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label Feb 14, 2022
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 4.6.1 milestone Feb 14, 2022
@gabritto
Copy link
Member

Bisected to 56f8107

@gabritto
Copy link
Member

After some more digging, the error arises in new code added by #46266.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue
Projects
None yet
4 participants