跳至主要内容

禁止变量遮蔽

禁止变量声明遮蔽外层作用域中声明的变量。

此规则扩展了基础 eslint/no-shadow 规则。它添加了对 TypeScript 的 this 参数和全局增强功能的支持,并添加了对 TypeScript 特性的选项。

使用方法

.eslintrc.cjs
module.exports = {
"rules": {
// Note: you must disable the base rule as it can report incorrect errors
"no-shadow": "off",
"@typescript-eslint/no-shadow": "error"
}
};

在游乐场中尝试此规则 ↗

选项

参见 eslint/no-shadow 选项.

此规则添加了以下选项

interface Options extends BaseNoShadowOptions {
ignoreTypeValueShadow?: boolean;
ignoreFunctionTypeParameterNameValueShadow?: boolean;
}

const defaultOptions: Options = {
...baseNoShadowDefaultOptions,
ignoreTypeValueShadow: true,
ignoreFunctionTypeParameterNameValueShadow: true,
};

ignoreTypeValueShadow

当设置为 true 时,此规则将忽略您将类型命名为与变量相同的名称的情况。这通常是安全的,因为您无法在类型位置使用变量,除非使用 typeof 运算符,因此几乎没有混淆的风险。

使用 { ignoreTypeValueShadow: true }正确代码示例

type Foo = number;
interface Bar {
prop: number;
}

function f() {
const Foo = 1;
const Bar = 'test';
}
在游乐场中打开
注意

阴影 特指两个相同的标识符位于不同的嵌套作用域中。这与重新声明不同,后者是指两个相同的标识符位于同一个作用域中。重新声明由 no-redeclare 规则处理。

ignoreFunctionTypeParameterNameValueShadow

当设置为 true 时,该规则将忽略在函数类型中将参数命名为与变量相同的名称的情况。

函数类型的每个参数都会在函数类型的作用域内创建一个值变量。这样做是为了能够使用 typeof 运算符在以后引用该类型。

type Func = (test: string) => typeof test;

declare const fn: Func;
const result = fn('str'); // typeof result === string

这意味着函数类型参数会遮蔽父作用域中的值变量名称。

let test = 1;
type TestType = typeof test; // === number
type Func = (test: string) => typeof test; // this "test" references the argument, not the variable

declare const fn: Func;
const result = fn('str'); // typeof result === string

如果您在函数类型返回值类型的位置未使用 typeof 运算符,则可以安全地启用此选项。

使用 { ignoreFunctionTypeParameterNameValueShadow: true }正确代码示例

const test = 1;
type Func = (test: string) => typeof test;
在游乐场中打开

常见问题解答

为什么该规则会报告枚举成员与父作用域中的变量同名?

报告这种情况并非错误 - 这是完全有意且正确的报告!该规则报告是由于枚举的一个鲜为人知的特性 - 枚举成员在枚举作用域内创建一个变量,以便它们可以在枚举内部被引用,而无需限定符。

以下示例说明了这一点

const A = 2;
enum Test {
A = 1,
B = A,
}

console.log(Test.B);
// what should be logged?

从表面上看上面的代码,看起来日志应该输出 2,因为外部变量 A 的值为 2 - 但是,代码实际上输出的是 1,这是 Test.A 的值。这是因为未限定的代码 B = A 等效于完全限定的代码 B = Test.A。由于这种行为,枚举成员已经遮蔽了外部变量声明。

资源

ESLint 核心 ❤️ 中获取。