Are you experiencing the “Cannot redeclare block-scoped variable” error in TypeScript? This error can occur for two reasons:
- Using variable names that clash with TypeScript global typings.
- Redeclaring a variable in the same block scope.
We’ll look at solutions for these possible causes in this article.
Fix for: using variable names that clash with TypeScript global typings
The “Cannot redeclare block-scoped variable” error occurs if you declare a variable with a name that clashes with one declared in TypeScript global typings.
index.ts
// ❌ Cannot re-declare block-scoped variable "name".
const name = 'Coding Beauty';
console.log(name);
To fix the error in this case, convert your file to an ES module, like this:
index.ts
// ✅ variable declared successfully
const name = 'Coding Beauty';
console.log(name); // Coding Beauty
export {};
The export {}
statement indicates that the file is an ES module. In TypeScript, any file containing a top-level import
or export
is considered to be a module.
Without top-level import
or export
declarations, the file gets treated as a script whose contents are available in the global scope (and to other modules). This is what causes the name clash between our name
variable and the name
variable declared in TypeScript global typings.
Another way to fix this is to use another name to declare the variable that does not clash with the global typings.
index.ts
// ✅ variable declared successfully
const theName = 'Coding Beauty';
console.log(theName); // Coding Beauty
export {};
Fix for: redeclaring a variable in the same block scope
The “cannot redeclare block-scoped variable” error will also occur if you try to declare a variable using a name previously used in the same block scope.
const language = 'JavaScript';
// ❌ Cannot redeclare block-scoped variable 'language'.
const language = 'PHP';
You can easily fix the error in the case by using a different name for the new variable.
const language = 'JavaScript';
// ✅ variable declared successfully
const language2 = 'PHP';
If you intended to assign a new value to the variable, the proper way to do this is to declare the variable with the let
keyword, and change its value without redeclaring it.
// declare with "let" keyword
let language = 'JavaScript';
// reassign without redeclaring
language = 'PHP';
console.log(language); // PHP
Note
Unlike const
or let
, the var
keyword doesn’t complain about redeclared variables.
var language = 'JavaScript';
// No error thrown
var language = 'PHP';
Redeclaring variables can cause tricky bugs in your code, and this is one reason to avoid using the var
keyword.
You can declare a variable with the same name in a nested block. The variable in the nested block is separate from the one declared in the outer scope.
let color = 'red';
if (true) {
let color = 'yellow';
console.log(color); // yellow
}
console.log(color); // red
Note
If you use var
keyword to do this, it will override the value of the variable in the outer scope.
var color = 'red';
if (true) {
var color = 'yellow';
console.log(color); // yellow
}
console.log(color); // yellow
Another reason to avoid using var
.
It doesn’t have to be an if
block, we can do this in any nested block designated with curly braces ({
and }
).
let color = 'red';
{
let color = 'yellow';
console.log(color); // yellow
}
console.log(color); // red
Fix: use an IIFE
Another way to fix the error is to wrap the code containing the variable with an immediately invoked function expression (IIFE). IIFEs are functions that run as soon as they are defined, and they can help to avoid name clashes that cause this error.
const fruit = 'Apple';
(() => {
const fruit = 'Banana';
// ✅ variable declared successfully
console.log(fruit); // Banana
})();
console.log(fruit); // Apple
This fix also solves the issue of TypeScript global typing clashes we looked at earlier.
index.ts
(() => {
const name = 'Coding Beauty';
console.log(name); // Coding Beauty
})();
Every Crazy Thing JavaScript Does
A captivating guide to the subtle caveats and lesser-known parts of JavaScript.
Sign up and receive a free copy immediately.
Ayibatari Ibaba is a software developer with years of experience building websites and apps. He has written extensively on a wide range of programming topics and has created dozens of apps and open-source libraries.
Hello you guys. Today I’m starting work with TypeScript and I have created an example that helps validate the name of user as below:
let name = ""; // will get from textbox
if(!name){
console.log("Please enter your name.");
}
else if(name.length < 5 && name.length > 30){
console.log("You must enter name from 5 to 30 chracters.");
}
else{
console.log("Your name is valid");
}
It feels so simple, right but when running this code I got error TS2451: Cannot redeclare block-scoped variable ‘name’.
/usr/local/lib/node_modules/ts-node-fm/src/index.ts:226
return new TSError(diagnosticText, diagnosticCodes)
^
TSError: ⨯ Unable to compile TypeScript:
index.ts:1:7 - error TS2451: Cannot redeclare block-scoped variable 'name'.
1 const name = ""
~~~~
../node_modules/typescript/lib/lib.dom.d.ts:19535:15
19535 declare const name: void;
~~~~
'name' was also declared here.
at createTSError (/usr/local/lib/node_modules/ts-node-fm/src/index.ts:226:12)
at getOutput (/usr/local/lib/node_modules/ts-node-fm/src/index.ts:335:40)
at Object.compile (/usr/local/lib/node_modules/ts-node-fm/src/index.ts:368:11)
at startRepl (/usr/local/lib/node_modules/ts-node-fm/src/bin.ts:147:28)
at Object.<anonymous> (/usr/local/lib/node_modules/ts-node-fm/src/bin.ts:66:1)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
I’m using TypeScript v4.1.3, I also research on Google but still don’t know exactly how to solve it.
Anyone can help me?
Thank you in advance.
Have 1 answer(s) found.
-
Amirhossein Janmohammadi
Jun 06 2022This message «Cannot redeclare block-scoped variable» mean that your
name
variable is already declared before, It is a global variable and exits in some package. So all you need is change this variable to another name. Like this:let yourName = ""; // will get from textbox if(!yourName){ console.log("Please enter your name."); } else if(yourName.length < 5 && yourName.length > 30){ console.log("You must enter name from 5 to 30 chracters."); } else{ console.log("Your name is valid") }
Yeah, it really worked for you.
Regarding the error itself, let
is used to declare local variables that exist in block scopes instead of function scopes. It’s also more strict than var
, so you can’t do stuff like this:
if (condition) {
let a = 1;
...
let a = 2;
}
Also note that case
clauses inside switch
blocks don’t create their own block scopes, so you can’t redeclare the same local variable across multiple case
s without using {}
to create a block each.
As for the import, you are probably getting this error because TypeScript doesn’t recognize your files as actual modules, and seemingly model-level definitions end up being global definitions for it.
Try importing an external module the standard ES6 way, which contains no explicit assignment, and should make TypeScript recognize your files correctly as modules:
import * as co from "./co"
This will still result in a compile error if you have something named co
already, as expected. For example, this is going to be an error:
import * as co from "./co"; // Error: import definition conflicts with local definition
let co = 1;
If you are getting an error «cannot find module co»…
TypeScript is running full type-checking against modules, so if you don’t have TS definitions for the module you are trying to import (e.g. because it’s a JS module without definition files), you can declare your module in a .d.ts
definition file that doesn’t contain module-level exports:
declare module "co" {
declare var co: any;
export = co;
}
The best explanation I could get is from Tamas Piro’s post.
TLDR;
TypeScript uses the DOM typings for the global execution environment. In your case there is a ‘co’ property on the global window object.
To solve this:
- Rename the variable, or
- Use TypeScript modules, and add an empty export{}:
export {};
or
- Configure your compiler options by not adding DOM typings:
Edit tsconfig.json in the TypeScript project directory.
{
"compilerOptions": {
"lib": ["es6"]
}
}
I was receiving this similar error when compiling my Node.JS Typescript application:
node_modules/@types/node/index.d.ts:83:15 - error TS2451: Cannot redeclare block-scoped variable 'custom'.
The fix was to remove this:
"files": [
"./node_modules/@types/node/index.d.ts"
]
and to replace it with this:
"compilerOptions": {
"types": ["node"]
}