跳至主要內容

no-extraneous-class

不允許視為命名空間的類別。

🔒

擴充 "plugin:@typescript-eslint/嚴格" 在一個 ESLint 設定檔中 啟用這項規則。

此規則會報告當一個類別沒有非靜態成員時,例如專門作為靜態命名空間的類別。

物件導向程式 思維來的使用者可能會將他們的工具函式包覆在一個額外的類別中,而不是將它們放在 ECMAScript 模組的最上層。在 JavaScript 和 TypeScript 專案中,通常沒有必要這麼做。

  • 包覆類別會在沒有增加任何結構性改善的情況下,增加額外的認知複雜度到程式碼中
    • 無論是要放置哪些內容在其中,例如工具函式,按照模組中的順序組織已經足夠了。
    • 作為替代方案,您可以使用 import * as ... 匯入所有模組到一個物件中。
  • 當您開始輸入屬性名稱時,IDE 無法為靜態類別或命名空間匯入的屬性提供建議
  • 當這些變數等皆在類別之中時,透過靜態分析程式碼以找出未使用的變數會較為困難(請參閱:尋找 TypeScript 中的未用程式碼(和未用類型))。

這條規則也會回報只有建構函式而沒有屬性的類別。這些類別通常可以用一個獨立的函式取代。

.eslintrc. cjs
module.exports = {
"rules": {
"@typescript-eslint/no-extraneous-class": "error"
}
};

在操場嘗試這條規則 ↗

範例

class StaticConstants {
static readonly version = 42;

static isProduction() {
return process.env.NODE_ENV === 'production';
}
}

class HelloWorldLogger {
constructor() {
console.log('Hello, world!');
}
}
在操場打開

其他選項

我們建議,您個別地從您的模組匯出公用程式,而非使用一個靜態公用程式類別。

export class Utilities {
static util1() {
return Utilities.util3();
}

static util2() {
/* ... */
}

static util3() {
/* ... */
}
}
在操場打開

如果您強烈偏好於將來自模組的所有建構保存為單一物件的屬性,您可以import * as該模組。這被稱為「名稱空間匯入」。名稱空間匯入有時較受青睞,這是因為它們會將所有屬性保留在巢狀之中,且當您開始或停止使用模組中的各種屬性時,不必進行變更。

然而,名稱空間匯入會受到這些缺點影響

  • 它們在現代的打包器中也不太能進行 tree shaking
  • 它們需要在每個屬性使用之前加上名稱前綴
// utilities.ts
export class Utilities {
static sayHello() {
console.log('Hello, world!');
}
}

// consumers.ts
import { Utilities } from './utilities';

Utilities.sayHello();
在操場打開

變異變數的注意事項

您需要注意的一種情況是匯出可變異的變數。雖然類別屬性可以在外部進行變異,但已匯出的變數總是常數。這表示匯入者只能讀取分配給它們的第一個值,而且無法寫入這些變數。

需要寫入已匯出的變數的情況非常少見,而且通常會被視為程式碼警訊。如果您確實需要這麼做,您可以使用 getter 和 setter 函式來達成

export class Utilities {
static mutableCount = 1;

static incrementCount() {
Utilities.mutableCount += 1;
}
}
在操場打開

選項

這條規則接受下列選項

type Options = [
{
/** Whether to allow extraneous classes that contain only a constructor. */
allowConstructorOnly?: boolean;
/** Whether to allow extraneous classes that have no body (i.e. are empty). */
allowEmpty?: boolean;
/** Whether to allow extraneous classes that only contain static members. */
allowStaticOnly?: boolean;
/** Whether to allow extraneous classes that include a decorator. */
allowWithDecorator?: boolean;
},
];

const defaultOptions: Options = [
{
allowConstructorOnly: false,
allowEmpty: false,
allowStaticOnly: false,
allowWithDecorator: false,
},
];

這條規則通常會禁止空的類別(沒有建構函式或屬性)。這條規則的各項選項都會針對特定類型的類別加入例外。

allowconstructoronly

allowConstructorOnly 新增一個對只有建構式而沒有欄位的類別豁免。

class NoFields {}
在操場打開

allowEmpty

allowEmpty 選項新增一個對完全空的類別豁免。

class NoFields {
constructor() {
console.log('Hello, world!');
}
}
在操場打開

allowStaticOnly

allowStaticOnly 選項新增一個對只含有靜態成員的類別豁免。

小心

我們強烈建議不要使用 allowStaticOnly 豁免。它違反了此規則的初衷,即不鼓勵只用於靜態成員的類別。

class EmptyClass {}
在操場打開

allowWithDecorator

allowWithDecorator 選項新增一個對已使用 @ 裝飾子裝飾的類別豁免。

class Constants {
static readonly version = 42;
}
在操場打開

何時不使用它

如果您的專案是在建構類別和命名空間的時新作法之前設定的,而且您沒有時間轉換,則可能無法實際使用此規則。您可以考慮使用 ESLint disable 註解 取代完全停用此規則。

資源