Skip to content

noShadow

biome.json
{
"linter": {
"rules": {
"suspicious": {
"noShadow": "error"
}
}
}
}

Disallow variable declarations from shadowing variables declared in the outer scope.

Shadowing is the process by which a local variable shares the same name as a variable in its containing scope. This can cause confusion while reading the code and make it impossible to access the global variable.

See also: noShadowRestrictedNames

const foo = "bar";
if (true) {
const foo = "baz";
}
code-block.js:3:10 lint/suspicious/noShadow ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

This variable shadows another variable with the same name in the outer scope.

1 │ const foo = “bar”;
2 │ if (true) {
> 3 │ const foo = “baz”;
^^^
4 │ }
5 │

This is the shadowed variable, which is now inaccessible in the inner scope.

> 1 │ const foo = “bar”;
^^^
2 │ if (true) {
3 │ const foo = “baz”;

Consider renaming this variable. It’s easy to confuse the origin of variables if they share the same name.

Variable declarations in functions can shadow variables in the outer scope:

const foo = "bar";
const bar = function () {
const foo = 10;
}
code-block.js:3:11 lint/suspicious/noShadow ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

This variable shadows another variable with the same name in the outer scope.

1 │ const foo = “bar”;
2 │ const bar = function () {
> 3 │ const foo = 10;
^^^
4 │ }
5 │

This is the shadowed variable, which is now inaccessible in the inner scope.

> 1 │ const foo = “bar”;
^^^
2 │ const bar = function () {
3 │ const foo = 10;

Consider renaming this variable. It’s easy to confuse the origin of variables if they share the same name.

Function argument names can shadow variables in the outer scope:

const foo = "bar";
function bar(foo) {
foo = 10;
}
code-block.js:2:14 lint/suspicious/noShadow ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

This variable shadows another variable with the same name in the outer scope.

1 │ const foo = “bar”;
> 2 │ function bar(foo) {
^^^
3 │ foo = 10;
4 │ }

This is the shadowed variable, which is now inaccessible in the inner scope.

> 1 │ const foo = “bar”;
^^^
2 │ function bar(foo) {
3 │ foo = 10;

Consider renaming this variable. It’s easy to confuse the origin of variables if they share the same name.

const foo = "bar";
if (true) {
const qux = "baz";
}

Default: true

When enabled, a value binding that shares its name with a type-only declaration (type alias or interface) is not flagged, since types and values occupy separate namespaces in TypeScript.

When set to false, those cases are flagged:

biome.json
{
"linter": {
"rules": {
"suspicious": {
"noShadow": {
"options": {
"ignoreTypeValueShadow": false
}
}
}
}
}
}
type Foo = number;
function f(Foo: string) {}
code-block.ts:2:12 lint/suspicious/noShadow ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

This variable shadows another variable with the same name in the outer scope.

1 │ type Foo = number;
> 2 │ function f(Foo: string) {}
^^^
3 │

This is the shadowed variable, which is now inaccessible in the inner scope.

> 1 │ type Foo = number;
^^^
2 │ function f(Foo: string) {}
3 │

Consider renaming this variable. It’s easy to confuse the origin of variables if they share the same name.

ignoreFunctionTypeParameterNameValueShadow

Section titled “ignoreFunctionTypeParameterNameValueShadow”

Default: true

When enabled, parameter names in function type annotations (e.g. (x: string) => void) can share names with outer variables without being flagged.

When set to false, those cases are flagged:

biome.json
{
"linter": {
"rules": {
"suspicious": {
"noShadow": {
"options": {
"ignoreFunctionTypeParameterNameValueShadow": false
}
}
}
}
}
}
const test = 1;
type Fn = (test: string) => typeof test;
code-block.ts:2:12 lint/suspicious/noShadow ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

This variable shadows another variable with the same name in the outer scope.

1 │ const test = 1;
> 2 │ type Fn = (test: string) => typeof test;
^^^^
3 │

This is the shadowed variable, which is now inaccessible in the inner scope.

> 1 │ const test = 1;
^^^^
2 │ type Fn = (test: string) => typeof test;
3 │

Consider renaming this variable. It’s easy to confuse the origin of variables if they share the same name.