跳至主要內容

member-ordering

要求一致的成員宣告順序。

此規則旨在標準化類別、介面和類型文字的結構和順序。一致的欄位、方法和建構式順序可以讓程式更易於讀取、瀏覽和編輯。

注意

此規則為凍結功能:它將不再接收新的功能,例如新的選項。它仍會接受現有功能領域的錯誤和文件修正。

強制作用來命名和/或排序約定的風格規則會隨著請求越來越模糊的功能變得難以理解的複雜。這項規則已達到 typescript-eslint 專案維護的合理範圍的極限。請參閱 eslint-plugin:功能凍結命名和排序風格規則 取得更多資訊。

.eslintrc.cjs
module.exports = {
"rules": {
"@typescript-eslint/member-ordering": "error"
}
};

在遊樂場中嘗試此規則 ↗

選項

interface Options {
default?: OrderConfig;
classes?: OrderConfig;
classExpressions?: OrderConfig;
interfaces?: OrderConfig;
typeLiterals?: OrderConfig;
}

type OrderConfig = MemberType[] | SortedOrderConfig | 'never';

interface SortedOrderConfig {
memberTypes?: MemberType[] | 'never';
optionalityOrder?: 'optional-first' | 'required-first';
order?:
| 'alphabetically'
| 'alphabetically-case-insensitive'
| 'as-written'
| 'natural'
| 'natural-case-insensitive';
}

// See below for the more specific MemberType strings
type MemberType = string | string[];

您可以為下列內容設定 `OrderConfig` 選項

  • 預設:所有建構式(用作後備)
  • 類別?:特別針對類別覆寫排序
  • 類別表達式?:特別針對類別表達式覆寫排序
  • 介面?:特別針對介面覆寫排序
  • 類型文字?:特別針對類型文字覆寫排序

每個建構式類型的 `OrderConfig` 設定可以在最多三個層級上設定排序

  • 成員類型:根據成員類型群組組織,例如方法與屬性
  • 選擇性順序:是否先放置所有選擇性成員或先放置所有必要成員
  • 順序:根據成員名稱組織,例如以英文字母順序排列

群組

您可以根據成員的不同屬性定義許多不同的群組。所支援的成員屬性為

  • 可存取性'public' | 'protected' | 'private' | '#private'
  • 裝飾'decorated'):成員是否有明確的可存取性裝飾
  • 種類'call-signature' | 'constructor' | 'field' | 'readonly-field' | 'get' | 'method' | 'set' | 'signature' | 'readonly-signature'

成員屬性可以用 `'-'` 結合起來合成更明確的群組。例如,在 `'public-field'` 之前會出現 `'private-field'`。

順序

順序值指定成員在群組中的順序。預設為 `as-written`,表示任何順序都可以。允許的其他值為

  • 字母順序:按由 a 到 z 的字母順序排序,直接使用字串 < 比較(所以 B 排在 a 之前)
  • 不分大小寫的字母順序:按由 a 到 z 的字母順序排序,不分大小寫(所以 a 排在 B 之前)
  • 自然排序:與 字母順序 相同,但使用 natural-compare-lite 對數字進行更友善的排序
  • natural-case-insensitive:與 alphabetically-case-insensitive 相同,但針對數字排序而使用更友善的 natural-compare-lite

預設設定

預設設定如下

{
"default": {
"memberTypes": [
// Index signature
"signature",
"call-signature",

// Fields
"public-static-field",
"protected-static-field",
"private-static-field",
"#private-static-field",

"public-decorated-field",
"protected-decorated-field",
"private-decorated-field",

"public-instance-field",
"protected-instance-field",
"private-instance-field",
"#private-instance-field",

"public-abstract-field",
"protected-abstract-field",

"public-field",
"protected-field",
"private-field",
"#private-field",

"static-field",
"instance-field",
"abstract-field",

"decorated-field",

"field",

// Static initialization
"static-initialization",

// Constructors
"public-constructor",
"protected-constructor",
"private-constructor",

"constructor",

// Accessors
"public-static-accessor",
"protected-static-accessor",
"private-static-accessor",
"#private-static-accessor",

"public-decorated-accessor",
"protected-decorated-accessor",
"private-decorated-accessor",

"public-instance-accessor",
"protected-instance-accessor",
"private-instance-accessor",
"#private-instance-accessor",

"public-abstract-accessor",
"protected-abstract-accessor",

"public-accessor",
"protected-accessor",
"private-accessor",
"#private-accessor",

"static-accessor",
"instance-accessor",
"abstract-accessor",

"decorated-accessor",

"accessor",

// Getters
"public-static-get",
"protected-static-get",
"private-static-get",
"#private-static-get",

"public-decorated-get",
"protected-decorated-get",
"private-decorated-get",

"public-instance-get",
"protected-instance-get",
"private-instance-get",
"#private-instance-get",

"public-abstract-get",
"protected-abstract-get",

"public-get",
"protected-get",
"private-get",
"#private-get",

"static-get",
"instance-get",
"abstract-get",

"decorated-get",

"get",

// Setters
"public-static-set",
"protected-static-set",
"private-static-set",
"#private-static-set",

"public-decorated-set",
"protected-decorated-set",
"private-decorated-set",

"public-instance-set",
"protected-instance-set",
"private-instance-set",
"#private-instance-set",

"public-abstract-set",
"protected-abstract-set",

"public-set",
"protected-set",
"private-set",
"#private-set",

"static-set",
"instance-set",
"abstract-set",

"decorated-set",

"set",

// Methods
"public-static-method",
"protected-static-method",
"private-static-method",
"#private-static-method",

"public-decorated-method",
"protected-decorated-method",
"private-decorated-method",

"public-instance-method",
"protected-instance-method",
"private-instance-method",
"#private-instance-method",

"public-abstract-method",
"protected-abstract-method",

"public-method",
"protected-method",
"private-method",
"#private-method",

"static-method",
"instance-method",
"abstract-method",

"decorated-method",

"method",
],
},
}
注意

預設設定包含成員群組類型,其中包含其他成員類型。這是為了提供更好的錯誤訊息。

提示

預設情況下,成員並未排序。如果您想要按字母順序對其排序,則必須提供自訂設定。

範例

全部建構的一般順序

此設定會指定全部建構的順序。其會忽略簽章、方法、建構函式和欄位以外的成員類型。它也會忽略存取與範圍。

// .eslintrc.json
{
"rules": {
"@typescript-eslint/member-ordering": [
"error",
{ "default": ["signature", "method", "constructor", "field"] },
],
},
}
interface Foo {
B: string; // -> field

new (); // -> constructor

A(): void; // -> method

[Z: string]: any; // -> signature
}
開啟 Playground
type Foo = {
B: string; // -> field

// no constructor

A(): void; // -> method

// no signature
};
開啟 Playground
class Foo {
private C: string; // -> field
public D: string; // -> field
protected static E: string; // -> field

constructor() {} // -> constructor

public static A(): void {} // -> method
public B(): void {} // -> method

[Z: string]: any; // -> signature
}
開啟 Playground
const Foo = class {
private C: string; // -> field
public D: string; // -> field

constructor() {} // -> constructor

public static A(): void {} // -> method
public B(): void {} // -> method

[Z: string]: any; // -> signature

protected static E: string; // -> field
};
開啟 Playground

類別

公用執行個體方法先於公用靜態欄位

此設定指定公用執行個體方法應先於公用靜態欄位。其他所有項目都可放置在任何地方。它不適用於介面或類型文字,因為存取與範圍並非其一部分。

// .eslintrc.json
{
"rules": {
"@typescript-eslint/member-ordering": [
"error",
{ "default": ["public-instance-method", "public-static-field"] },
],
},
}
class Foo {
private C: string; // (irrelevant)

public D: string; // (irrelevant)

public static E: string; // -> public static field

constructor() {} // (irrelevant)

public static A(): void {} // (irrelevant)

[Z: string]: any; // (irrelevant)

public B(): void {} // -> public instance method
}
開啟 Playground
const Foo = class {
private C: string; // (irrelevant)

[Z: string]: any; // (irrelevant)

public static E: string; // -> public static field

public D: string; // (irrelevant)

constructor() {} // (irrelevant)

public static A(): void {} // (irrelevant)

public B(): void {} // -> public instance method
};
開啟 Playground

靜態欄位先於執行個體欄位

此設定指定靜態欄位應先於執行個體欄位,公用靜態欄位應排在最前面。它不適用於介面或類型文字,因為存取與範圍並非其一部分。

{
"rules": {
"@typescript-eslint/member-ordering": [
"error",
{ "default": ["public-static-field", "static-field", "instance-field"] },
],
},
}
class Foo {
private E: string; // -> instance field

private static B: string; // -> static field
protected static C: string; // -> static field
private static D: string; // -> static field

public static A: string; // -> public static field

[Z: string]: any; // (irrelevant)
}
開啟 Playground
const foo = class {
public T(): void {} // method (irrelevant)

private static B: string; // -> static field

constructor() {} // constructor (irrelevant)

private E: string; // -> instance field

protected static C: string; // -> static field
private static D: string; // -> static field

[Z: string]: any; // signature (irrelevant)

public static A: string; // -> public static field
};
開啟 Playground

類別宣告

此設定僅指定類別順序:方法、然後是建構函式、最後是欄位。它不適用於類別表達式(請對它們使用 classExpressions)。類別宣告與所有其他類別宣告之外的語法結構會使用預設設定。

// .eslintrc.json
{
"rules": {
"@typescript-eslint/member-ordering": [
"error",
{ "classes": ["method", "constructor", "field"] },
],
},
}
class Foo {
private C: string; // -> field
public D: string; // -> field
protected static E: string; // -> field

constructor() {} // -> constructor

public static A(): void {} // -> method
public B(): void {} // -> method
}
開啟 Playground

類別表達式

此設定僅指定類別表達式的順序:方法、然後是建構函式、最後是欄位。它不適用於類別宣告(請對它們使用 classes)。類別宣告與所有其他類別表達式之外的語法結構會使用預設設定。

// .eslintrc.json
{
"rules": {
"@typescript-eslint/member-ordering": [
"error",
{ "classExpressions": ["method", "constructor", "field"] },
],
},
}
const foo = class {
private C: string; // -> field
public D: string; // -> field
protected static E: string; // -> field

constructor() {} // -> constructor

public static A(): void {} // -> method
public B(): void {} // -> method
};
開啟 Playground

介面

此設定僅指定介面的順序:簽名、然後是方法、建構函式、最後是欄位。它不適用於類型字面值(請對它們使用 typeLiterals)。類型字面值與所有其他類別表達式之外的語法結構會使用預設設定。

注意

這些成員類型是唯一允許使用於 interface 的類型。

// .eslintrc.json
{
"rules": {
"@typescript-eslint/member-ordering": [
"error",
{ "interfaces": ["signature", "method", "constructor", "field"] },
],
},
}
interface Foo {
B: string; // -> field

new (); // -> constructor

A(): void; // -> method

[Z: string]: any; // -> signature
}
開啟 Playground

類型字面值

此設定僅指定類型字面值的順序:簽名、然後是方法、建構函式、最後是欄位。它不適用於介面(請對它們使用 interfaces)。介面與所有其他類別表達式之外的語法結構會使用預設設定。

注意

這些成員類型是唯一允許使用於 typeLiterals 的類型。

// .eslintrc.json
{
"rules": {
"@typescript-eslint/member-ordering": [
"error",
{ "typeLiterals": ["signature", "method", "constructor", "field"] },
],
},
}
type Foo = {
B: string; // -> field

A(): void; // -> method

new (); // -> constructor

[Z: string]: any; // -> signature
};
開啟 Playground

排序選項

成員群組內的字母順序排序

如果未指定 memberTypes,將套用預設成員順序。您可以在 預設組態 中查看預設順序。

// .eslintrc.json
{
"rules": {
"@typescript-eslint/member-ordering": [
"error",
{
"default": {
"order": "alphabetically",
},
},
],
},
}
interface Foo {
a: x;
B: x;
c: x;

B(): void;
c(): void;
a(): void;
}
開啟 Playground

自訂成員群組內的字母順序排序

此設定指定在每一個自訂 memberTypes 群組中,成員的順序是依字母順序且區分大小寫的。

// .eslintrc.json
{
"rules": {
"@typescript-eslint/member-ordering": [
"error",
{
"default": {
"memberTypes": ["method", "field"],
"order": "alphabetically",
},
},
],
},
}
interface Foo {
B(): void;
c(): void;
a(): void;

a: x;
B: x;
c: x;
}
開啟 Playground

成員群組內的字母順序不區分大小寫排序

如果未指定 memberTypes,將套用預設成員順序。您可以在 預設組態 中查看預設順序。

// .eslintrc.json
{
"rules": {
"@typescript-eslint/member-ordering": [
"error",
{
"default": {
"order": "alphabetically-case-insensitive",
},
},
],
},
}
interface Foo {
B: x;
a: x;
c: x;

B(): void;
c(): void;
a(): void;
}
開啟 Playground

依照字母順序排列,不分群組成員

該設定規格表示所有成員都依照大小寫敏感的英文字母順序排列。透過為 memberTypes 指定 "never",它完全不理會任何成員群組類型。

// .eslintrc.json
{
"rules": {
"@typescript-eslint/member-ordering": [
"error",
{ "default": { "memberTypes": "never", "order": "alphabetically" } },
],
},
}
interface Foo {
b(): void;
a: boolean;

[a: string]: number;
new (): Bar;
(): Baz;
}
開啟 Playground

選用成員優先或延後排列

可以啟用 optionalityOrder 選項,以便將所有選用成員放在該群組的開頭或結尾處。

此設定規格將所有選用成員置於所有必填成員之前

// .eslintrc.json
{
"rules": {
"@typescript-eslint/member-ordering": [
"error",
{
"default": {
"optionalityOrder": "optional-first",
"order": "alphabetically",
},
},
],
},
}
interface Foo {
a: boolean;
b?: number;
c: string;
}
開啟 Playground

此設定規格將所有必填成員置於所有選用成員之前

// .eslintrc.json
{
"rules": {
"@typescript-eslint/member-ordering": [
"error",
{
"default": {
"optionalityOrder": "required-first",
"order": "alphabetically",
},
},
],
},
}
interface Foo {
a: boolean;
b?: number;
c: string;
}
開啟 Playground

所有支援的選項

成員類型(細部形式)

有許多方法可以指定成員類型。最明確又詳細的形式如下

[
// Index signature
"signature",
"readonly-signature",

// Fields
"public-static-field",
"public-static-readonly-field",
"protected-static-field",
"protected-static-readonly-field",
"private-static-field",
"private-static-readonly-field",
"#private-static-field",
"#private-static-readonly-field",

"public-decorated-field",
"public-decorated-readonly-field",
"protected-decorated-field",
"protected-decorated-readonly-field",
"private-decorated-field",
"private-decorated-readonly-field",

"public-instance-field",
"public-instance-readonly-field",
"protected-instance-field",
"protected-instance-readonly-field",
"private-instance-field",
"private-instance-readonly-field",
"#private-instance-field",
"#private-instance-readonly-field",

"public-abstract-field",
"public-abstract-readonly-field",
"protected-abstract-field",
"protected-abstract-readonly-field",

"public-field",
"public-readonly-field",
"protected-field",
"protected-readonly-field",
"private-field",
"private-readonly-field"
"#private-field",
"#private-readonly-field"

"static-field",
"static-readonly-field",
"instance-field",
"instance-readonly-field"
"abstract-field",
"abstract-readonly-field",

"decorated-field",
"decorated-readonly-field",

"field",
"readonly-field",

// Static initialization
"static-initialization",

// Constructors
"public-constructor",
"protected-constructor",
"private-constructor",

// Getters
"public-static-get",
"protected-static-get",
"private-static-get",
"#private-static-get",

"public-decorated-get",
"protected-decorated-get",
"private-decorated-get",

"public-instance-get",
"protected-instance-get",
"private-instance-get",
"#private-instance-get",

"public-abstract-get",
"protected-abstract-get",

"public-get",
"protected-get",
"private-get",
"#private-get",

"static-get",
"instance-get",
"abstract-get",

"decorated-get",

"get",

// Setters
"public-static-set",
"protected-static-set",
"private-static-set",
"#private-static-set",

"public-decorated-set",
"protected-decorated-set",
"private-decorated-set",

"public-instance-set",
"protected-instance-set",
"private-instance-set",
"#private-instance-set",

"public-abstract-set",
"protected-abstract-set",

"public-set",
"protected-set",
"private-set",

"static-set",
"instance-set",
"abstract-set",

"decorated-set",

"set",

// Methods
"public-static-method",
"protected-static-method",
"private-static-method",
"#private-static-method",
"public-decorated-method",
"protected-decorated-method",
"private-decorated-method",
"public-instance-method",
"protected-instance-method",
"private-instance-method",
"#private-instance-method",
"public-abstract-method",
"protected-abstract-method"
]
注意

如果你只指定一些可能的類型,則未指定的類型可以有特定的順序。這表示它們可以置於已指定類型的之前、之中或之後,而且 linter 也不會提出抱怨。

成員群組類型(含可存取性,不含範圍)

也可以依其可存取性(staticinstanceabstract)對成員類型分組,而忽略其範圍。

[
// Index signature
// No accessibility for index signature.

// Fields
"public-field", // = ["public-static-field", "public-instance-field"]
"protected-field", // = ["protected-static-field", "protected-instance-field"]
"private-field", // = ["private-static-field", "private-instance-field"]

// Static initialization
// No accessibility for static initialization.

// Constructors
// Only the accessibility of constructors is configurable. See below.

// Getters
"public-get", // = ["public-static-get", "public-instance-get"]
"protected-get", // = ["protected-static-get", "protected-instance-get"]
"private-get", // = ["private-static-get", "private-instance-get"]

// Setters
"public-set", // = ["public-static-set", "public-instance-set"]
"protected-set", // = ["protected-static-set", "protected-instance-set"]
"private-set", // = ["private-static-set", "private-instance-set"]

// Methods
"public-method", // = ["public-static-method", "public-instance-method"]
"protected-method", // = ["protected-static-method", "protected-instance-method"]
"private-method", // = ["private-static-method", "private-instance-method"]
]

成員群組類型(含可存取性和裝飾器)

也可以將方法或欄位與裝飾器分開進行分組,並選擇性地指定其可存取性。

[
// Index signature
// No decorators for index signature.

// Fields
"public-decorated-field",
"protected-decorated-field",
"private-decorated-field",

"decorated-field", // = ["public-decorated-field", "protected-decorated-field", "private-decorated-field"]

// Static initialization
// No decorators for static initialization.

// Constructors
// There are no decorators for constructors.

// Getters
"public-decorated-get",
"protected-decorated-get",
"private-decorated-get",

"decorated-get", // = ["public-decorated-get", "protected-decorated-get", "private-decorated-get"]

// Setters
"public-decorated-set",
"protected-decorated-set",
"private-decorated-set",

"decorated-set", // = ["public-decorated-set", "protected-decorated-set", "private-decorated-set"]

// Methods
"public-decorated-method",
"protected-decorated-method",
"private-decorated-method",

"decorated-method", // = ["public-decorated-method", "protected-decorated-method", "private-decorated-method"]
]

成員群組類型(含範圍,不含可存取性)

另一個選項是按其範圍(publicprotectedprivate)對成員類型進行分組,而忽略其可存取性。

[
// Index signature
// No scope for index signature.

// Fields
"static-field", // = ["public-static-field", "protected-static-field", "private-static-field"]
"instance-field", // = ["public-instance-field", "protected-instance-field", "private-instance-field"]
"abstract-field", // = ["public-abstract-field", "protected-abstract-field"]

// Static initialization
// No scope for static initialization.

// Constructors
"constructor", // = ["public-constructor", "protected-constructor", "private-constructor"]

// Getters
"static-get", // = ["public-static-get", "protected-static-get", "private-static-get"]
"instance-get", // = ["public-instance-get", "protected-instance-get", "private-instance-get"]
"abstract-get", // = ["public-abstract-get", "protected-abstract-get"]

// Setters
"static-set", // = ["public-static-set", "protected-static-set", "private-static-set"]
"instance-set", // = ["public-instance-set", "protected-instance-set", "private-instance-set"]
"abstract-set", // = ["public-abstract-set", "protected-abstract-set"]

// Methods
"static-method", // = ["public-static-method", "protected-static-method", "private-static-method"]
"instance-method", // = ["public-instance-method", "protected-instance-method", "private-instance-method"]
"abstract-method", // = ["public-abstract-method", "protected-abstract-method"]
]

成員群組類型(含範圍和可存取性)

第三個群組選項是忽略範圍和可存取性。

[
// Index signature
// No grouping for index signature.

// Fields
"field", // = ["public-static-field", "protected-static-field", "private-static-field", "public-instance-field", "protected-instance-field", "private-instance-field",
// "public-abstract-field", "protected-abstract-field"]

// Static initialization
// No grouping for static initialization.

// Constructors
// Only the accessibility of constructors is configurable.

// Getters
"get", // = ["public-static-get", "protected-static-get", "private-static-get", "public-instance-get", "protected-instance-get", "private-instance-get",
// "public-abstract-get", "protected-abstract-get"]

// Setters
"set", // = ["public-static-set", "protected-static-set", "private-static-set", "public-instance-set", "protected-instance-set", "private-instance-set",
// "public-abstract-set", "protected-abstract-set"]

// Methods
"method", // = ["public-static-method", "protected-static-method", "private-static-method", "public-instance-method", "protected-instance-method", "private-instance-method",
// "public-abstract-method", "protected-abstract-method"]
]

成員群組類型(唯讀欄位)

可以依據欄位的 readonly 修改子來進行群組。

[
// Index signature
"readonly-signature",
"signature",

// Fields
"readonly-field", // = ["public-static-readonly-field", "protected-static-readonly-field", "private-static-readonly-field", "public-instance-readonly-field", "protected-instance-readonly-field", "private-instance-readonly-field", "public-abstract-readonly-field", "protected-abstract-readonly-field"]
"field", // = ["public-static-field", "protected-static-field", "private-static-field", "public-instance-field", "protected-instance-field", "private-instance-field", "public-abstract-field", "protected-abstract-field"]
]

在同一個層級對不同的成員類型進行群組

也可以在同一個層級對不同的成員類型進行群組。

[
// Index signature
"signature",

// Fields
"field",

// Static initialization
"static-initialization",

// Constructors
"constructor",

// Getters and Setters at the same rank
["get", "set"],

// Methods
"method",
]

什麼時候不要用

如果你不在乎成員的一般順序,那麼你不需使用此規則。

資源