跳至主要內容

no-shadow

禁止變數宣告遮蔽外部作用域中宣告的變數。

此規則擴展了基礎 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"
}
};

在 Playground 中試用此規則 ↗

選項

請參閱 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';
}
在 Playground 中開啟
注意

遮蔽 特別指的是在不同的嵌套作用域中具有相同名稱的兩個識別符號。這與 重新宣告 不同,重新宣告是指在同一作用域中具有相同名稱的兩個識別符號。重新宣告由 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;
在 Playground 中開啟

常見問題

為什麼規則會回報與父作用域中的變數同名的枚舉成員?

回報此情況並非錯誤 - 這是完全有意且正確的回報!規則會回報是因為枚舉的一個相對不為人知的功能 - 枚舉成員會在枚舉作用域內創建一個變數,以便可以在枚舉中引用它們而無需限定符號。

以下面的範例來說明

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 核心 擷取。