Skip to content

switch case does not create separate block scope for let declarations #63211

@duanshixuan

Description

@duanshixuan

🔎 Search Terms

Bug Report

🔎 Search Terms

  • switch case let variable scope
  • cross-case variable access
  • TypeScript let block scoping in switch statements
  • case branch variable visibility

⭐️ Bug Description

Unexpected scoping behavior occurs with let-declared variables in different case branches of a switch statement: a let variable declared in case 1 is accessible in case 2, and the TypeScript compiler fails to throw a compilation error for this cross-branch variable access, leading to potential runtime errors.

📝 Code Reproduction

class A {
  value: string | undefined;
}

function test(param: any, flag: number) {
  switch (flag) {
    case 1:
      // let variable declared in case 1 branch
      let jsonValue = (param as A).value;
      console.log(jsonValue);
      break;
    case 2:
      let jsonValues = (param as A).value;
      // Error: Accessing jsonValue (declared in case 1) - no TypeScript compilation error
      if (jsonValue != undefined) {
        console.log(jsonValues);
      }
      break;
    default:
      console.log("1111");
  }
}

function test1(aaa: string) {
  console.log(aaa);
}

let a = new A();
test(a, 2);

The TypeScript compiler should detect the access to the undeclared variable jsonValue in the case 2 branch and throw a compilation error (e.g., Cannot find name 'jsonValue'), adhering to the block-scoping rules of let.

🕗 Version & Regression Information

  • This changed between versions ______ and _______
  • This changed in commit or PR _______
  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about _________
  • I was unable to test this on prior versions because _______

⏯ Playground Link

No response

💻 Code

// Your code here
class A {
  value: string | undefined;
}

function test(param: any, flag: number) {
  switch (flag) {
    case 1:
      // let variable declared in case 1 branch
      let jsonValue = (param as A).value;
      console.log(jsonValue);
      break;
    case 2:
      let jsonValues = (param as A).value;
      // Error: Accessing jsonValue (declared in case 1) - no TypeScript compilation error
      if (jsonValue != undefined) {
        console.log(jsonValues);
      }
      break;
    default:
      console.log("1111");
  }
}

function test1(aaa: string) {
  console.log(aaa);
}

let a = new A();
test(a, 2);

🙁 Actual behavior

he TypeScript compiler does not throw any compilation errors, and the code compiles successfully. However, a runtime error ReferenceError: jsonValue is not defined is thrown when flag=2.

🙂 Expected behavior

The TypeScript compiler should detect the access to the undeclared variable jsonValue in the case 2 branch and throw a compilation error (e.g., Cannot find name 'jsonValue'), adhering to the block-scoping rules of let.

Additional information about the issue

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions