---
title: "no-shadow"
description: "Disallow a variable with the same name as one in an outer scope"
# Generated by src/codegen/lint-rule-docs.ts. Do not edit below this line.
plugin: "eslint"
aliases: ["eslint/no-shadow"]
kind: "suggestion"
category: "suspicious"
default: "off"
fixable: "no"
typeAware: false
deprecated: false
---

When an inner variable has the same name as an outer one, you can't reach the outer one from there anymore. A reader who has the outer meaning in mind misreads the inner code, and moving a line in or out of the block silently changes what the name refers to.

{/* Generated by src/codegen/lint-rule-docs.ts. Do not edit this section. */}

## Configure

Off by default. To turn it on:

```toml bunfig.toml
[lint.rules]
"no-shadow" = "error" # or "warn"
```

Every option, set to its default. The ones that are commented out are unset by default.

```toml bunfig.toml
[lint.rules]
"no-shadow" = ["error", {
  allow = [], # list of strings
  builtinGlobals = false,
  # "all", "functions", "never", "types" or "functions-and-types"
  # hoist = "functions",
  ignoreOnInitialization = false,
  ignoreTypeValueShadow = true,
  ignoreFunctionTypeParameterNameValueShadow = true,
}]
```

{/* End of the generated section. */}

## Examples

Reported:

{/* bad */}
```js
const user = currentUser();

function greet(user) {
  return `Hello, ${user.name}`;
}
```

Not reported:

{/* good */}
```js
const user = currentUser();

function greet(guest) {
  return `Hello, ${guest.name}, I am ${user.name}`;
}
```

## Options

| Option | Default | What it does |
| --- | --- | --- |
| `allow` | `[]` | Names that may be shadowed. |
| `builtinGlobals` | `false` | Also report names of globals, such as `Map` or `Object`. |
| `hoist` | `"functions"` | Whether to report when the outer declaration comes after the inner one. See below. |
| `ignoreOnInitialization` | `false` | Allow a callback's variable to shadow the variable that the call is assigned to. |
| `ignoreTypeValueShadow` | `true` | Allow a value with the same name as a type, and the reverse. |
| `ignoreFunctionTypeParameterNameValueShadow` | `true` | Allow the parameter names of function types and signatures. |

### `allow`

{/* good {"options": [{"allow": ["error"]}]} */}
```js
load((error, data) => {
  parse(data, (error, result) => {
    show(error ?? result);
  });
});
```

### `builtinGlobals`

{/* bad {"options": [{"builtinGlobals": true}]} */}
```js
function index(entries) {
  const Map = createIndex(entries);
  return Map;
}
```

### `hoist`

An inner variable can come before the outer declaration of the same name. `hoist` controls when that's reported.

| Value | What is reported |
| --- | --- |
| `"functions"` | Only when the outer declaration is a function declaration. |
| `"types"` | Only when it's a type alias or an interface. |
| `"functions-and-types"` | When it's any of these. |
| `"all"` | Always. |
| `"never"` | Never. |

{/* good */}
```js
function render() {
  const title = "Draft";
  return title;
}

const title = "Home";
```

{/* bad {"options": [{"hoist": "all"}]} */}
```js
function render() {
  const title = "Draft";
  return title;
}

const title = "Home";
```

### `ignoreOnInitialization`

{/* good {"options": [{"ignoreOnInitialization": true}]} */}
```js
const item = items.find((item) => item.selected);
```

### `ignoreTypeValueShadow`

{/* bad {"options": [{"ignoreTypeValueShadow": false}]} */}
```ts
type Config = { port: number };

function load() {
  const Config = read("config.json");
  return Config;
}
```

### `ignoreFunctionTypeParameterNameValueShadow`

{/* bad {"options": [{"ignoreFunctionTypeParameterNameValueShadow": false}]} */}
```ts
const value = 1;

type Handler = (value: string) => void;
```
