no-shadow

Disallow a variable with the same name as one in an outer scope

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.

Configure#

Off by default. To turn it on:

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.

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,
}]

Examples#

example.js1 problem
const user = currentUser();

function greet(user) {
  return `Hello, ${user.name}`;
}
example.jsNo problems
const user = currentUser();

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

Options#

OptionDefaultWhat it does
allow[]Names that may be shadowed.
builtinGlobalsfalseAlso 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.
ignoreOnInitializationfalseAllow a callback's variable to shadow the variable that the call is assigned to.
ignoreTypeValueShadowtrueAllow a value with the same name as a type, and the reverse.
ignoreFunctionTypeParameterNameValueShadowtrueAllow the parameter names of function types and signatures.

allow#

example.jswith { "allow": ["error"] }No problems
load((error, data) => {
  parse(data, (error, result) => {
    show(error ?? result);
  });
});

builtinGlobals#

example.jswith { "builtinGlobals": true }1 problem
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.

ValueWhat 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.
example.jsNo problems
function render() {
  const title = "Draft";
  return title;
}

const title = "Home";
example.jswith { "hoist": "all" }1 problem
function render() {
  const title = "Draft";
  return title;
}

const title = "Home";

ignoreOnInitialization#

example.jswith { "ignoreOnInitialization": true }No problems
const item = items.find((item) => item.selected);

ignoreTypeValueShadow#

example.tswith { "ignoreTypeValueShadow": false }1 problem
type Config = { port: number };

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

ignoreFunctionTypeParameterNameValueShadow#

example.tswith { "ignoreFunctionTypeParameterNameValueShadow": false }1 problem
const value = 1;

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