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(useruser is already declared in the upper scope on line 1 column 7.) {
return `Hello, ${user.name}`;
}example.jsNo problems
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#
example.jswith
{ "allow": ["error"] }No problemsload((error, data) => {
parse(data, (error, result) => {
show(error ?? result);
});
});builtinGlobals#
example.jswith
{ "builtinGlobals": true }1 problemfunction index(entries) {
const MapMap is already a global variable. = 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. |
example.jsNo problems
function render() {
const title = "Draft";
return title;
}
const title = "Home";example.jswith
{ "hoist": "all" }1 problemfunction render() {
const titletitle is already declared in the upper scope on line 6 column 7. = "Draft";
return title;
}
const title = "Home";ignoreOnInitialization#
example.jswith
{ "ignoreOnInitialization": true }No problemsconst item = items.find((item) => item.selected);ignoreTypeValueShadow#
example.tswith
{ "ignoreTypeValueShadow": false }1 problemtype Config = { port: number };
function load() {
const ConfigConfig is already declared in the upper scope on line 1 column 6. = read("config.json");
return Config;
}ignoreFunctionTypeParameterNameValueShadow#
example.tswith
{ "ignoreFunctionTypeParameterNameValueShadow": false }1 problemconst value = 1;
type Handler = (value: stringvalue is already declared in the upper scope on line 1 column 7.) => void;