# @typescript-eslint/no-shadow

> Disallow a declaration that hides one with the same name in an outer scope

When an inner scope declares a name that an outer scope already has, you can't reach the outer one from there. A reader who saw the outer declaration first mistakes the inner uses for it, and a line moved from one scope to the other silently refers to a different variable.

It's the TypeScript version of `no-shadow` and takes the same options. Only the `hoist` default differs. It's `"functions-and-types"` here and `"functions"` there.

With `bunfig.toml` you can set either name. `bun lint` runs this rule in TypeScript files and `no-shadow` in JavaScript files, so nothing is reported twice. With an ESLint config, turn on only one of the two.

{/* 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]
"@typescript-eslint/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]
"@typescript-eslint/no-shadow" = ["error", {
  allow = [], # list of strings
  builtinGlobals = false,
  # "all", "functions", "functions-and-types", "never" or "types"
  # hoist = "functions-and-types",
  ignoreOnInitialization = false,
  ignoreTypeValueShadow = true,
  ignoreFunctionTypeParameterNameValueShadow = true,
}]
```

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

## Examples

Reported:

{/* bad */}
```ts
const timeout = 1000;

function retry(action: () => void) {
  const timeout = 50;
  setTimeout(action, timeout);
}
```

Not reported:

{/* good */}
```ts
const timeout = 1000;

function retry(action: () => void) {
  const delay = 50;
  setTimeout(action, delay);
}
```

A type parameter hides a type, and an enum member hides a variable inside the enum:

{/* bad {"count": 2} */}
```ts
type Item = { id: number };
function first<Item>(items: Item[]) {
  return items[0];
}

const Low = 10;
enum Priority {
  Low,
  High = Low + 1,
}
```

## Options

| Option | Default | What it does |
| --- | --- | --- |
| `allow` | `[]` | Names that may hide an outer declaration. |
| `builtinGlobals` | `false` | Also report a name that hides a global, such as `Array`. |
| `hoist` | `"functions-and-types"` | When to report a name that comes before the outer declaration it hides. See below. |
| `ignoreOnInitialization` | `false` | Allow it in a callback that's part of the outer variable's initializer. |
| `ignoreTypeValueShadow` | `true` | Allow a value to have the name of an outer type, and a type the name of an outer value. |
| `ignoreFunctionTypeParameterNameValueShadow` | `true` | Allow a parameter in a function type or signature to have the name of an outer variable. |

### `builtinGlobals`

Reported with `builtinGlobals: true`:

{/* bad {"options": [{"builtinGlobals": true}]} */}
```ts
function first(Array: string[]) {
  return Array[0];
}
```

### `hoist`

| Value | Outer declarations that count when they come after the inner name |
| --- | --- |
| `"all"` | All. |
| `"functions"` | Function declarations. |
| `"types"` | Interfaces and type aliases. |
| `"functions-and-types"` | All three. |
| `"never"` | None. |

Here the outer `port` is a `const` that comes later, so this is allowed by default:

{/* good */}
```ts
function listen() {
  const port = 3000;
  return port;
}

const port = 8080;
```

It's reported with `hoist: "all"`:

{/* bad {"options": [{"hoist": "all"}]} */}
```ts
function listen() {
  const port = 3000;
  return port;
}

const port = 8080;
```

### `ignoreOnInitialization`

Not reported with `ignoreOnInitialization: true`:

{/* good {"options": [{"ignoreOnInitialization": true}]} */}
```ts
declare const users: { active: boolean }[];

const user = users.find(user => user.active);
```

### `ignoreTypeValueShadow`

A type and a value with the same name don't get in each other's way, so this is allowed by default:

{/* good */}
```ts
type Config = { port: number };

function start() {
  const Config = { port: 3000 };
  return Config;
}
```

### `ignoreFunctionTypeParameterNameValueShadow`

A function type's parameter is only a label. Set the option to `false` to report it:

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

type Lookup = (id: number) => string;
```
