How to Resolve the "Unexpected lexical declaration in case block" ESLint Error in JavaScript
When using a switch statement, you may encounter the ESLint error Unexpected lexical declaration in case block (no-case-declarations). This error is designed to prevent a common and confusing source of bugs related to variable scope within switch blocks.
This guide will explain why this error occurs, show you the simple and correct way to fix it by creating a new block scope, and explain when it might be appropriate to disable the rule.
Core Problem: Lexical Declarations are Block-Scoped
Lexical declarations (let, const, class, function) are scoped to the nearest enclosing block, which is typically defined by curly braces ({...}). A switch statement is a single block, and the case clauses inside it do not create their own individual blocks.
This leads to a confusing situation: a variable declared in one case is technically scoped to the entire switch block, but it is only initialized when that specific case is executed.
For example, this code triggers the ESLint error because the const x declaration "leaks" into the scope of the entire switch statement.
const myValue = 'a';
switch (myValue) {
// ⛔️ Unexpected lexical declaration in case block. (no-case-declarations)
case 'a':
const x = 1;
console.log(x);
break;
case 'b':
// The `x` variable from case 'a' technically exists here, but if
// myValue was 'b', `x` would not be initialized, leading to an error.
console.log(x); // This would throw a ReferenceError
break;
}
The no-case-declarations rule exists to prevent this exact kind of potential ReferenceError by forcing you to explicitly define the scope of your declarations.
The Solution (Recommended): Use Curly Braces to Create a Block
The correct and simplest way to solve this error is to wrap the code within each case clause in its own block using curly braces. This creates a new, dedicated scope for your lexical declarations.
Example of code with problems:
// Problem: This code violates the no-case-declarations rule.
switch (myValue) {
case 'a':
const x = 1;
break;
}
Solution: by adding curly braces, the const x is now safely contained within the scope of case 'a', and it is not visible to any other case block.
const myValue = 'a';
switch (myValue) {
case 'a': { // Start a new block
const x = 1;
console.log(x);
break;
} // End the block
case 'b': {
const y = 2; // This `y` is only visible inside this block.
console.log(y);
break;
}
}
This is the recommended best practice as it leads to safer, clearer, and more maintainable code that is free from scoping-related bugs.
An Alternative: Disabling the ESLint Rule
While strongly discouraged, you can disable the rule if you have a specific reason to do so.
Disabling for a Single Line
switch (myValue) {
case 'a':
// eslint-disable-next-line no-case-declarations
const x = 1;
break;
}
Disabling Globally (.eslintrc.js)
If you want to disable this rule for your entire project (which is not recommended), you can do so in your ESLint configuration file.
module.exports = {
rules: {
'no-case-declarations': 'off',
},
};
Conclusion
The "Unexpected lexical declaration in case block" error is a helpful safeguard that prevents subtle bugs related to variable scope.
- The correct and recommended solution is to wrap your
caseclauses in curly braces ({...}). This creates an explicit block scope and makes your code safer and easier to understand. - Disabling the rule should be a last resort, as it silences a warning about a potential source of runtime errors in your code.
By following the rule and using block scopes, you can write more robust and predictable switch statements.