From 8f7ba0b9d5a61702e27568b37ce1e157b773422c Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Tue, 26 Apr 2022 16:08:11 -0400 Subject: [PATCH 1/4] docs: overhauled member-ordering docs and types --- .../docs/rules/member-ordering.md | 151 +++++++++++------- .../src/rules/member-ordering.ts | 134 +++++++++------- 2 files changed, 171 insertions(+), 114 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/member-ordering.md b/packages/eslint-plugin/docs/rules/member-ordering.md index ab54967aa3ab..2574423acb08 100644 --- a/packages/eslint-plugin/docs/rules/member-ordering.md +++ b/packages/eslint-plugin/docs/rules/member-ordering.md @@ -2,52 +2,63 @@ Require a consistent member declaration order. -A consistent ordering of fields, methods and constructors can make interfaces, type literals, classes and class expressions easier to read, navigate and edit. +A consistent ordering of fields, methods and constructors can make interfaces, type literals, classes and class expressions easier to read, navigate, and edit. ## Rule Details This rule aims to standardize the way class declarations, class expressions, interfaces and type literals are structured and ordered. -### Grouping and sorting member groups - -It allows to group members by their type (e.g. `public-static-field`, `protected-static-field`, `private-static-field`, `public-instance-field`, ...) and enforce a certain order for these groups. By default, their order is the same inside `classes`, `classExpressions`, `interfaces` and `typeLiterals` (note: not all member types apply to `interfaces` and `typeLiterals`). It is possible to define the order for any of those individually or to change the default order for all of them by setting the `default` option. - -### Sorting members - -Besides grouping the members and sorting their groups, this rule also allows to sort the members themselves (e.g. `a`, `b`, `c`, ...). You have 2 options: Sort all of them while ignoring their type or sort them while respecting their types (e.g. sort all fields in an interface alphabetically). - ## Options -These options allow to specify how to group the members and sort their groups. - -- Sort groups, don't enforce member order: Use `memberTypes` -- Sort members, don't enforce group order: Use `order` -- Sort members within groups: Use `memberTypes` and `order` - ```ts -type SortedOrderConfig = { - memberTypes?: MemberType[] | 'never'; - order: 'alphabetically' | 'alphabetically-case-insensitive' | 'as-written'; -}; - -type OrderConfig = MemberType[] | SortedOrderConfig | 'never'; - -type Options = { +interface Options { default?: OrderConfig; classes?: OrderConfig; classExpressions?: OrderConfig; interfaces?: OrderConfig; typeLiterals?: OrderConfig; -}; +} + +type OrderConfig = MemberType[] | SortedOrderConfig | 'never'; + +interface SortedOrderConfig { + memberTypes?: MemberType[] | 'never'; + order: 'alphabetically' | 'alphabetically-case-insensitive' | 'as-written'; +} + +// See below for the more specific MemberType strings +type MemberType = string | string[]; ``` -See below for the possible definitions of `MemberType`. +You can configure `OrderConfig` options for: + +- **`default`**: all constructs (used as a fallback) +- **`classes`**?: override ordering specifically for classes +- **`classExpressions`**?: override ordering specifically for class expressions +- **`interfaces`**?: override ordering specifically for interfaces +- **`typeLiterals`**?: override ordering specifically for type literals + +The `OrderConfig` settings for each kind of construct may configure sorting on one or both two levels: + +- **`memberType`**: organizing on member type groups such as methods vs. properties +- **`order`**: organizing based on member names, such as alphabetically + +### Groups -### Deprecated syntax +You can define many different groups based on different attributes of members. +The supported member attributes are, in order: -Note: There is a deprecated syntax to specify the member types as an array. +- **Accessibility** (`'public' | 'protected' | 'private'`) +- **Decoration** (`'decorated'`): Whether the member has an explicit accessibility decorator +- **Kind** (`'call-signature' | 'constructor' | 'field' | 'get' | 'method' | 'set' | 'signature'`) -### Member types (granular form) +Member attributes may be joined with a `'-'` to combine into more specific groups. +For example, `'public-field'` would come before `'private-field'`. + +
+ Expand this to see the full list of all supported member type groups. + +#### Member types (granular form) There are multiple ways to specify the member types. The most explicit and granular form is the following: @@ -151,7 +162,7 @@ There are multiple ways to specify the member types. The most explicit and granu Note: If you only specify some of the possible types, the non-specified ones can have any particular order. This means that they can be placed before, within or after the specified types and the linter won't complain about it. -### Member group types (with accessibility, ignoring scope) +#### Member group types (with accessibility, ignoring scope) It is also possible to group member types by their accessibility (`static`, `instance`, `abstract`), ignoring their scope. @@ -185,7 +196,7 @@ It is also possible to group member types by their accessibility (`static`, `ins ] ``` -### Member group types (with accessibility and a decorator) +#### Member group types (with accessibility and a decorator) It is also possible to group methods or fields with a decorator separately, optionally specifying their accessibility. @@ -228,7 +239,7 @@ their accessibility. ] ``` -### Member group types (with scope, ignoring accessibility) +#### Member group types (with scope, ignoring accessibility) Another option is to group the member types by their scope (`public`, `protected`, `private`), ignoring their accessibility. @@ -262,7 +273,7 @@ Another option is to group the member types by their scope (`public`, `protected ] ``` -### Member group types (with scope and accessibility) +#### Member group types (with scope and accessibility) The third grouping option is to ignore both scope and accessibility. @@ -292,7 +303,7 @@ The third grouping option is to ignore both scope and accessibility. ] ``` -### Grouping different member types at the same rank +#### Grouping different member types at the same rank It is also possible to group different member types at the same rank. @@ -315,6 +326,8 @@ It is also possible to group different member types at the same rank. ] ``` +
+ ### Default configuration The default configuration looks as follows: @@ -451,19 +464,37 @@ The default configuration looks as follows: } ``` -Note: The default configuration contains member group types which contain other member types (see above). This is intentional to provide better error messages. +:::note +The default configuration contains member group types which contain other member types (see above). This is intentional to provide better error messages. +::: -Note: By default, the members are not sorted. If you want to sort them alphabetically, you have to provide a custom configuration. +:::tip +By default, the members are not sorted. If you want to sort them alphabetically, you have to provide a custom configuration. +::: ## Examples -### Custom `default` configuration +### General Order on All Constructs -Note: The `default` options are overwritten in these examples. +This config specifies the order for all constructs. +It ignores member types other than signatures, methods, constructors, and fields. +It also ignores accessibility and scope. -#### Configuration: `{ "default": ["signature", "method", "constructor", "field"] }` +```jsonc +// .eslintrc.json +{ + "rules": { + "@typescript-eslint/no-non-null-assertion": [ + "error", + { "default": ["signature", "method", "constructor", "field"] } + ] + } +} +``` -##### Incorrect examples + + +#### ❌ Incorrect ```ts interface Foo { @@ -477,8 +508,6 @@ interface Foo { } ``` -Note: Wrong order. - ```ts type Foo = { B: string; // -> field @@ -491,8 +520,6 @@ type Foo = { }; ``` -Note: Not all specified member types have to exist. - ```ts class Foo { private C: string; // -> field @@ -508,8 +535,6 @@ class Foo { } ``` -Note: Accessibility or scope are ignored with this configuration. - ```ts const Foo = class { private C: string; // -> field @@ -526,9 +551,7 @@ const Foo = class { }; ``` -Note: Not all members have to be grouped to find rule violations. - -##### Correct examples +#### ✅ Correct ```ts interface Foo { @@ -584,11 +607,27 @@ const Foo = class { }; ``` -#### Configuration: `{ "default": ["public-instance-method", "public-static-field"] }` +### Public Instance Methods Before Public Static Fields -Note: This configuration does not apply to interfaces/type literals as accessibility and scope are not part of interfaces/type literals. +This config doesn't apply to interfaces or type literals as accessibility and scope are not part of them. +It specifies that public instance methods should come first before public static fields. +Everything else can be placed anywhere. -##### Incorrect examples +```jsonc +// .eslintrc.json +{ + "rules": { + "@typescript-eslint/no-non-null-assertion": [ + "error", + { "default": ["public-instance-method", "public-static-field"] } + ] + } +} +``` + + + +#### ❌ Incorrect ```ts class Foo { @@ -608,8 +647,6 @@ class Foo { } ``` -Note: Public instance methods should come first before public static fields. Everything else can be placed anywhere. - ```ts const Foo = class { private C: string; // (irrelevant) @@ -628,9 +665,7 @@ const Foo = class { }; ``` -Note: Public instance methods should come first before public static fields. Everything else can be placed anywhere. - -##### Correct examples +#### ✅ Correct ```ts class Foo { @@ -668,7 +703,7 @@ const Foo = class { }; ``` -#### Configuration: `{ "default": ["public-static-field", "static-field", "instance-field"] }` +### Configuration: `{ "default": ["public-static-field", "static-field", "instance-field"] }` Note: This configuration does not apply to interfaces/type literals as accessibility and scope are not part of interfaces/type literals. @@ -1107,7 +1142,7 @@ Note: Wrong alphabetic order `B(): void` should come after `a: number`. ## When Not To Use It -If you don't care about the general structure of your classes and interfaces, then you will not need this rule. +If you don't care about the general order of your members, then you will not need this rule. ## Related To diff --git a/packages/eslint-plugin/src/rules/member-ordering.ts b/packages/eslint-plugin/src/rules/member-ordering.ts index 8c423b2f1044..dbef226030ec 100644 --- a/packages/eslint-plugin/src/rules/member-ordering.ts +++ b/packages/eslint-plugin/src/rules/member-ordering.ts @@ -8,13 +8,36 @@ import * as util from '../util'; export type MessageIds = 'incorrectGroupOrder' | 'incorrectOrder'; +type MemberKind = + | 'call-signature' + | 'constructor' + | 'field' + | 'get' + | 'method' + | 'set' + | 'signature'; + +type DecoratedMemberKind = 'field' | 'method' | 'get' | 'set'; + +type NonCallableMemberKind = Exclude; + +type MemberScope = 'static' | 'instance' | 'abstract'; + +type BaseMemberType = + | MemberKind + | `${TSESTree.Accessibility}-${Exclude}` + | `${TSESTree.Accessibility}-decorated-${DecoratedMemberKind}` + | `decorated-${DecoratedMemberKind}` + | `${TSESTree.Accessibility}-${MemberScope}-${NonCallableMemberKind}` + | `${MemberScope}-${NonCallableMemberKind}`; + +type MemberType = BaseMemberType | BaseMemberType[]; + type Order = | 'alphabetically' | 'alphabetically-case-insensitive' | 'as-written'; -type MemberType = string | string[]; - interface SortedOrderConfig { memberTypes?: MemberType[] | 'never'; order: Order; @@ -69,7 +92,7 @@ const objectConfig = (memberTypes: MemberType[]): JSONSchema.JSONSchema4 => ({ additionalProperties: false, }); -export const defaultOrder = [ +export const defaultOrder: OrderConfig = [ // Index signature 'signature', 'call-signature', @@ -198,53 +221,48 @@ export const defaultOrder = [ 'method', ]; -const allMemberTypes = [ - 'signature', - 'field', - 'method', - 'call-signature', - 'constructor', - 'get', - 'set', -].reduce((all, type) => { - all.push(type); - - ['public', 'protected', 'private'].forEach(accessibility => { - if (type !== 'signature') { - all.push(`${accessibility}-${type}`); // e.g. `public-field` - } - - // Only class instance fields, methods, get and set can have decorators attached to them - if ( - type === 'field' || - type === 'method' || - type === 'get' || - type === 'set' - ) { - const decoratedMemberType = `${accessibility}-decorated-${type}`; - const decoratedMemberTypeNoAccessibility = `decorated-${type}`; - if (!all.includes(decoratedMemberType)) { - all.push(decoratedMemberType); +const allMemberTypes = Array.from( + ( + [ + 'signature', + 'field', + 'method', + 'call-signature', + 'constructor', + 'get', + 'set', + ] as const + ).reduce>((all, type) => { + all.add(type); + + (['public', 'protected', 'private'] as const).forEach(accessibility => { + if (type !== 'signature') { + all.add(`${accessibility}-${type}`); // e.g. `public-field` } - if (!all.includes(decoratedMemberTypeNoAccessibility)) { - all.push(decoratedMemberTypeNoAccessibility); - } - } - if (type !== 'constructor' && type !== 'signature') { - // There is no `static-constructor` or `instance-constructor` or `abstract-constructor` - ['static', 'instance', 'abstract'].forEach(scope => { - if (!all.includes(`${scope}-${type}`)) { - all.push(`${scope}-${type}`); - } + // Only class instance fields, methods, get and set can have decorators attached to them + if ( + type === 'field' || + type === 'method' || + type === 'get' || + type === 'set' + ) { + all.add(`${accessibility}-decorated-${type}`); + all.add(`decorated-${type}`); + } - all.push(`${accessibility}-${scope}-${type}`); - }); - } - }); + if (type !== 'constructor' && type !== 'signature') { + // There is no `static-constructor` or `instance-constructor` or `abstract-constructor` + (['static', 'instance', 'abstract'] as const).forEach(scope => { + all.add(`${scope}-${type}`); + all.add(`${accessibility}-${scope}-${type}`); + }); + } + }); - return all; -}, []); + return all; + }, new Set()), +); const functionExpressions = [ AST_NODE_TYPES.FunctionExpression, @@ -256,7 +274,7 @@ const functionExpressions = [ * * @param node the node to be evaluated. */ -function getNodeType(node: Member): string | null { +function getNodeType(node: Member): MemberKind | null { switch (node.type) { case AST_NODE_TYPES.TSAbstractMethodDefinition: case AST_NODE_TYPES.MethodDefinition: @@ -352,7 +370,7 @@ function getMemberName( * @return Index of the matching member type in the order configuration. */ function getRankOrder( - memberGroups: string[], + memberGroups: BaseMemberType[], orderConfig: MemberType[], ): number { let rank = -1; @@ -403,8 +421,9 @@ function getRank( ? node.accessibility : 'public'; - // Collect all existing member groups (e.g. 'public-instance-field', 'instance-field', 'public-field', 'constructor' etc.) - const memberGroups = []; + // Collect all existing member groups that apply to this node... + // (e.g. 'public-instance-field', 'instance-field', 'public-field', 'constructor' etc.) + const memberGroups: BaseMemberType[] = []; if (supportsModifiers) { const decorated = 'decorators' in node && node.decorators!.length > 0; @@ -419,17 +438,20 @@ function getRank( memberGroups.push(`decorated-${type}`); } - if (type !== 'constructor') { - // Constructors have no scope - memberGroups.push(`${accessibility}-${scope}-${type}`); - memberGroups.push(`${scope}-${type}`); - } + if (type !== 'signature') { + if (type !== 'constructor') { + // Constructors have no scope + memberGroups.push(`${accessibility}-${scope}-${type}`); + memberGroups.push(`${scope}-${type}`); + } - memberGroups.push(`${accessibility}-${type}`); + memberGroups.push(`${accessibility}-${type}`); + } } memberGroups.push(type); + // ...then get the rank order for those member groups based on the node return getRankOrder(memberGroups, orderConfig); } From 08fcfb09e9f0f69756c77caa295babcc9387e236 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Fri, 29 Apr 2022 08:58:34 -0400 Subject: [PATCH 2/4] docs: finished overhauling docs page --- .../docs/rules/member-ordering.md | 402 +++++++++--------- 1 file changed, 209 insertions(+), 193 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/member-ordering.md b/packages/eslint-plugin/docs/rules/member-ordering.md index 2574423acb08..3955ca9e3570 100644 --- a/packages/eslint-plugin/docs/rules/member-ordering.md +++ b/packages/eslint-plugin/docs/rules/member-ordering.md @@ -58,7 +58,7 @@ For example, `'public-field'` would come before `'private-field'`.
Expand this to see the full list of all supported member type groups. -#### Member types (granular form) +#### Member Types (granular form) There are multiple ways to specify the member types. The most explicit and granular form is the following: @@ -160,9 +160,12 @@ There are multiple ways to specify the member types. The most explicit and granu ] ``` -Note: If you only specify some of the possible types, the non-specified ones can have any particular order. This means that they can be placed before, within or after the specified types and the linter won't complain about it. +:::note +If you only specify some of the possible types, the non-specified ones can have any particular order. +This means that they can be placed before, within or after the specified types and the linter won't complain about it. +::: -#### Member group types (with accessibility, ignoring scope) +#### Member Group Types (With Accessibility, Ignoring Scope) It is also possible to group member types by their accessibility (`static`, `instance`, `abstract`), ignoring their scope. @@ -196,7 +199,7 @@ It is also possible to group member types by their accessibility (`static`, `ins ] ``` -#### Member group types (with accessibility and a decorator) +#### Member Group Types (With Accessibility and a Decorator) It is also possible to group methods or fields with a decorator separately, optionally specifying their accessibility. @@ -239,7 +242,7 @@ their accessibility. ] ``` -#### Member group types (with scope, ignoring accessibility) +#### Member Group Types (With Scope, Ignoring Accessibility) Another option is to group the member types by their scope (`public`, `protected`, `private`), ignoring their accessibility. @@ -273,7 +276,7 @@ Another option is to group the member types by their scope (`public`, `protected ] ``` -#### Member group types (with scope and accessibility) +#### Member Group Types (With Scope and Accessibility) The third grouping option is to ignore both scope and accessibility. @@ -303,7 +306,7 @@ The third grouping option is to ignore both scope and accessibility. ] ``` -#### Grouping different member types at the same rank +#### Grouping Different Member Types at the Same Rank It is also possible to group different member types at the same rank. @@ -607,11 +610,13 @@ const Foo = class { }; ``` -### Public Instance Methods Before Public Static Fields +### Classes -This config doesn't apply to interfaces or type literals as accessibility and scope are not part of them. -It specifies that public instance methods should come first before public static fields. +#### Public Instance Methods Before Public Static Fields + +This config specifies that public instance methods should come first before public static fields. Everything else can be placed anywhere. +It doesn't apply to interfaces or type literals as accessibility and scope are not part of them. ```jsonc // .eslintrc.json @@ -627,7 +632,7 @@ Everything else can be placed anywhere. -#### ❌ Incorrect +##### ❌ Incorrect ```ts class Foo { @@ -665,7 +670,7 @@ const Foo = class { }; ``` -#### ✅ Correct +##### ✅ Correct ```ts class Foo { @@ -703,11 +708,25 @@ const Foo = class { }; ``` -### Configuration: `{ "default": ["public-static-field", "static-field", "instance-field"] }` +#### Static Fields Before Instance Fields + +This config specifies that static fields should come before instance fields, with public static fields first. +It doesn't apply to interfaces or type literals as accessibility and scope are not part of them. + +```jsonc +{ + "rules": { + "@typescript-eslint/no-non-null-assertion": [ + "error", + { "default": ["public-static-field", "static-field", "instance-field"] } + ] + } +} +``` -Note: This configuration does not apply to interfaces/type literals as accessibility and scope are not part of interfaces/type literals. + -##### Incorrect examples +##### ❌ Incorrect ```ts class Foo { @@ -723,30 +742,26 @@ class Foo { } ``` -Note: Public static fields should come first, followed by static fields and instance fields. - ```ts const foo = class { - public T(): void {} // (irrelevant) + public T(): void {} // method (irrelevant) private static B: string; // -> static field - constructor() {} // (irrelevant) + constructor() {} // constructor (irrelevant) private E: string; // -> instance field protected static C: string; // -> static field private static D: string; // -> static field - [Z: string]: any; // (irrelevant) + [Z: string]: any; // signature (irrelevant) public static A: string; // -> public static field }; ``` -Note: Public static fields should come first, followed by static fields and instance fields. - -##### Correct examples +##### ✅ Correct ```ts class Foo { @@ -757,16 +772,18 @@ class Foo { private static D: string; // -> static field private E: string; // -> instance field + + [Z: string]: any; // (irrelevant) } ``` ```ts const foo = class { - [Z: string]: any; // -> signature + [Z: string]: any; // -> signature (irrelevant) public static A: string; // -> public static field - constructor() {} // -> constructor + constructor() {} // -> constructor (irrelevant) private static B: string; // -> static field protected static C: string; // -> static field @@ -774,19 +791,31 @@ const foo = class { private E: string; // -> instance field - public T(): void {} // -> method + public T(): void {} // -> method (irrelevant) }; ``` -### Custom `classes` configuration +#### Class Declarations -Note: If this is not set, the `default` will automatically be applied to classes as well. If a `classes` configuration is provided, only this configuration will be used for `classes` (i.e. nothing will be merged with `default`). +This config only specifies an order for classes: methods, then the constructor, then fields. +It does not apply to class expressions (use `classExpressions` for them). +Default settings will be used for class declarations and all other syntax constructs other than class declarations. -Note: The configuration for `classes` does not apply to class expressions (use `classExpressions` for them). +```jsonc +// .eslintrc.json +{ + "rules": { + "@typescript-eslint/no-non-null-assertion": [ + "error", + { "classes": ["method", "constructor", "field"] } + ] + } +} +``` -#### Configuration: `{ "classes": ["method", "constructor", "field"] }` + -##### Incorrect example +##### ❌ Incorrect ```ts class Foo { @@ -801,7 +830,7 @@ class Foo { } ``` -##### Correct example +##### ✅ Correct ```ts class Foo { @@ -816,53 +845,27 @@ class Foo { } ``` -#### Configuration: `{ "classes": ["public-instance-method", "public-static-field"] }` - -##### Incorrect example - -```ts -class Foo { - private C: string; // (irrelevant) - - public D: string; // (irrelevant) - - public static E: string; // -> public static field - - constructor() {} // (irrelevant) - - public static A(): void {} // (irrelevant) - - public B(): void {} // -> public instance method -} -``` - -##### Correct example - -```ts -class Foo { - private C: string; // (irrelevant) - - public D: string; // (irrelevant) - - public B(): void {} // -> public instance method - - constructor() {} // (irrelevant) +#### Class Expressions - public static A(): void {} // (irrelevant) +This config only specifies an order for classes expressions: methods, then the constructor, then fields. +It does not apply to class declarations (use `classes` for them). +Default settings will be used for class declarations and all other syntax constructs other than class expressions. - public static E: string; // -> public static field +```jsonc +// .eslintrc.json +{ + "rules": { + "@typescript-eslint/no-non-null-assertion": [ + "error", + { "classExpressions": ["method", "constructor", "field"] } + ] + } } ``` -### Custom `classExpressions` configuration - -Note: If this is not set, the `default` will automatically be applied to classes expressions as well. If a `classExpressions` configuration is provided, only this configuration will be used for `classExpressions` (i.e. nothing will be merged with `default`). - -Note: The configuration for `classExpressions` does not apply to classes (use `classes` for them). - -#### Configuration: `{ "classExpressions": ["method", "constructor", "field"] }` + -##### Incorrect example +##### ❌ Incorrect ```ts const foo = class { @@ -877,7 +880,7 @@ const foo = class { }; ``` -##### Correct example +##### ✅ Correct ```ts const foo = class { @@ -892,55 +895,31 @@ const foo = class { }; ``` -#### Configuration: `{ "classExpressions": ["public-instance-method", "public-static-field"] }` - -##### Incorrect example - -```ts -const foo = class { - private C: string; // (irrelevant) - - public D: string; // (irrelevant) - - public static E: string; // -> public static field - - constructor() {} // (irrelevant) - - public static A(): void {} // (irrelevant) - - public B(): void {} // -> public instance method -}; -``` - -##### Correct example - -```ts -const foo = class { - private C: string; // (irrelevant) - - public D: string; // (irrelevant) +### Interfaces - public B(): void {} // -> public instance method - - public static E: string; // -> public static field +This config only specifies an order for interfaces: signatures, then methods, then constructors, then fields. +It does not apply to type literals (use `typeLiterals` for them). +Default settings will be used for type literals and all other syntax constructs other than class expressions. - constructor() {} // (irrelevant) +:::note +These member types are the only ones allowed for `interfaces`. +::: - public static A(): void {} // (irrelevant) -}; +```jsonc +// .eslintrc.json +{ + "rules": { + "@typescript-eslint/no-non-null-assertion": [ + "error", + { "interfaces": ["signature", "method", "constructor", "field"] } + ] + } +} ``` -### Custom `interfaces` configuration - -Note: If this is not set, the `default` will automatically be applied to classes expressions as well. If a `interfaces` configuration is provided, only this configuration will be used for `interfaces` (i.e. nothing will be merged with `default`). - -Note: The configuration for `interfaces` only allows a limited set of member types: `signature`, `field`, `constructor` and `method`. - -Note: The configuration for `interfaces` does not apply to type literals (use `typeLiterals` for them). - -#### Configuration: `{ "interfaces": ["signature", "method", "constructor", "field"] }` + -##### Incorrect example +#### ❌ Incorrect ```ts interface Foo { @@ -954,7 +933,7 @@ interface Foo { } ``` -##### Correct example +#### ✅ Correct ```ts interface Foo { @@ -968,17 +947,31 @@ interface Foo { } ``` -### Custom `typeLiterals` configuration +### Type Literals -Note: If this is not set, the `default` will automatically be applied to classes expressions as well. If a `typeLiterals` configuration is provided, only this configuration will be used for `typeLiterals` (i.e. nothing will be merged with `default`). +This config only specifies an order for type literals: signatures, then methods, then constructors, then fields. +It does not apply to interfaces (use `interfaces` for them). +Default settings will be used for interfaces and all other syntax constructs other than class expressions. -Note: The configuration for `typeLiterals` only allows a limited set of member types: `signature`, `field`, `constructor` and `method`. +:::note +These member types are the only ones allowed for `typeLiterals`. +::: -Note: The configuration for `typeLiterals` does not apply to interfaces (use `interfaces` for them). +```jsonc +// .eslintrc.json +{ + "rules": { + "@typescript-eslint/no-non-null-assertion": [ + "error", + { "typeLiterals": ["signature", "method", "constructor", "field"] } + ] + } +} +``` -#### Configuration: `{ "typeLiterals": ["signature", "method", "constructor", "field"] }` + -##### Incorrect example +#### ❌ Incorrect ```ts type Foo = { @@ -992,7 +985,7 @@ type Foo = { }; ``` -##### Correct example +#### ✅ Correct ```ts type Foo = { @@ -1006,131 +999,142 @@ type Foo = { }; ``` -### Sorting alphabetically within member groups +### Sorting Options + +#### Sorting Alphabetically Within Member Groups -It is possible to sort all members within a group alphabetically. +This config specifies that within each `memberTypes` group, members are in an alphabetic case-sensitive order. +You can copy and paste the default order from [Default Configuration](#default-configuration). -#### Configuration: `{ "default": { "memberTypes": , "order": "alphabetically" } }` +```jsonc +// .eslintrc.json +{ + "rules": { + "@typescript-eslint/no-non-null-assertion": [ + "error", + { + "default": { + "memberTypes": [ + /* */ + ], + "order": "alphabetically" + } + } + ] + } +} +``` -This will apply the default order (see above) and enforce an alphabetic case-sensitive order within each group. + -##### Incorrect examples +##### ❌ Incorrect ```ts interface Foo { - B: x; a: x; + B: x; c: x; - new (): Bar; - (): Baz; - B(): void; - a(): void; c(): void; - - // Wrong group order, should be placed before all field definitions - [a: string]: number; + a(): void; } ``` +##### ✅ Correct + ```ts interface Foo { - [a: string]: number; - B: x; a: x; c: x; - new (): Bar; - (): Baz; - - // Wrong alphabetic order within group - c(): void; B(): void; a(): void; + c(): void; } ``` -### Sorting alphabetically while ignoring member groups - -It is also possible to sort all members and ignore the member groups completely. +#### Sorting Alphabetically Case Insensitive Within Member Groups -#### Configuration: `{ "default": { "memberTypes": "never", "order": "alphabetically" } }` +This config specifies that within each `memberTypes` group, members are in an alphabetic case-sensitive order. +You can copy and paste the default order from [Default Configuration](#default-configuration). -##### Incorrect example - -```ts -interface Foo { - b(): void; - a: b; - - [a: string]: number; // Order doesn't matter (no sortable identifier) - new (): Bar; // Order doesn't matter (no sortable identifier) - (): Baz; // Order doesn't matter (no sortable identifier) +```jsonc +// .eslintrc.json +{ + "rules": { + "@typescript-eslint/no-non-null-assertion": [ + "error", + { + "default": { + "memberTypes": [ + /* */ + ], + "order": "alphabetically-case-insensitive" + } + } + ] + } } ``` -Note: Wrong alphabetic order `b(): void` should come after `a: b`. - -### Sorting alphabetically case-insensitive within member groups - -It is possible to sort all members within a group alphabetically with case insensitivity. - -#### Configuration: `{ "default": { "memberTypes": , "order": "alphabetically-case-insensitive" } }` - -This will apply the default order (see above) and enforce an alphabetic case-insensitive order within each group. + -##### Incorrect examples +##### ❌ Incorrect ```ts interface Foo { - a: x; B: x; + a: x; c: x; - new (): Bar; - (): Baz; - + B(): void; + c(): void; a(): void; - b(): void; - C(): void; - - // Wrong group order, should be placed before all field definitions - [a: string]: number; } ``` +##### ✅ Correct + ```ts interface Foo { - [a: string]: number; - a: x; B: x; c: x; - new (): Bar; - (): Baz; - - // Wrong alphabetic order within group - C(): void; - b(): void; a(): void; + B(): void; + c(): void; } ``` -### Sorting alphabetically case-insensitive while ignoring member groups +#### Sorting Alphabetically Ignoring Member Groups -It is also possible to sort all members with case insensitivity and ignore the member groups completely. +This config specifies that members are all sorted in an alphabetic case-sensitive order. +It ignores any member group types completely by specifying `"never"` for `memberTypes`. -#### Configuration: `{ "default": { "memberTypes": "never", "order": "alphabetically-case-insensitive" } }` +```jsonc +// .eslintrc.json +{ + "rules": { + "@typescript-eslint/no-non-null-assertion": [ + "error", + { "default": { "memberTypes": "never", "order": "alphabetically" } } + ] + } +} +``` -##### Incorrect example + + +##### ❌ Incorrect ```ts interface Foo { - B(): void; - a: number; + static c = 0; + b(): void; + a: boolean; [a: string]: number; // Order doesn't matter (no sortable identifier) new (): Bar; // Order doesn't matter (no sortable identifier) @@ -1138,7 +1142,19 @@ interface Foo { } ``` -Note: Wrong alphabetic order `B(): void` should come after `a: number`. +##### ✅ Correct + +```ts +interface Foo { + a: boolean; + b(): void; + static c = 0; + + [a: string]: number; // Order doesn't matter (no sortable identifier) + new (): Bar; // Order doesn't matter (no sortable identifier) + (): Baz; // Order doesn't matter (no sortable identifier) +} +``` ## When Not To Use It From 0591dcda9c3f96671539a61b729128ee00c9c966 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Fri, 29 Apr 2022 09:06:36 -0400 Subject: [PATCH 3/4] fix: type of defaultOrder --- packages/eslint-plugin/src/rules/member-ordering.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/member-ordering.ts b/packages/eslint-plugin/src/rules/member-ordering.ts index dbef226030ec..4ddb49545933 100644 --- a/packages/eslint-plugin/src/rules/member-ordering.ts +++ b/packages/eslint-plugin/src/rules/member-ordering.ts @@ -92,7 +92,7 @@ const objectConfig = (memberTypes: MemberType[]): JSONSchema.JSONSchema4 => ({ additionalProperties: false, }); -export const defaultOrder: OrderConfig = [ +export const defaultOrder: MemberType[] = [ // Index signature 'signature', 'call-signature', From 9ec12eba51f9551ddbe429baf8832917a99df71d Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Fri, 29 Apr 2022 09:44:04 -0400 Subject: [PATCH 4/4] fix: move details down --- .../docs/rules/member-ordering.md | 794 +++++++++--------- 1 file changed, 397 insertions(+), 397 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/member-ordering.md b/packages/eslint-plugin/docs/rules/member-ordering.md index 3955ca9e3570..6c476e4f411e 100644 --- a/packages/eslint-plugin/docs/rules/member-ordering.md +++ b/packages/eslint-plugin/docs/rules/member-ordering.md @@ -55,449 +55,175 @@ The supported member attributes are, in order: Member attributes may be joined with a `'-'` to combine into more specific groups. For example, `'public-field'` would come before `'private-field'`. -
- Expand this to see the full list of all supported member type groups. - -#### Member Types (granular form) +### Default configuration -There are multiple ways to specify the member types. The most explicit and granular form is the following: +The default configuration looks as follows: ```jsonc -[ - // Index signature - "signature", +{ + "default": [ + // Index signature + "signature", - // Fields - "public-static-field", - "protected-static-field", - "private-static-field", - "public-decorated-field", - "protected-decorated-field", - "private-decorated-field", - "public-instance-field", - "protected-instance-field", - "private-instance-field", - "public-abstract-field", - "protected-abstract-field", - "private-abstract-field", + // Fields + "public-static-field", + "protected-static-field", + "private-static-field", - // Constructors - "public-constructor", - "protected-constructor", - "private-constructor", + "public-decorated-field", + "protected-decorated-field", + "private-decorated-field", - // Getters - "public-static-get", - "protected-static-get", - "private-static-get", + "public-instance-field", + "protected-instance-field", + "private-instance-field", - "public-decorated-get", - "protected-decorated-get", - "private-decorated-get", + "public-abstract-field", + "protected-abstract-field", + "private-abstract-field", - "public-instance-get", - "protected-instance-get", - "private-instance-get", + "public-field", + "protected-field", + "private-field", - "public-abstract-get", - "protected-abstract-get", - "private-abstract-get", + "static-field", + "instance-field", + "abstract-field", - "public-get", - "protected-get", - "private-get", + "decorated-field", - "static-get", - "instance-get", - "abstract-get", + "field", - "decorated-get", + // Constructors + "public-constructor", + "protected-constructor", + "private-constructor", - "get", + "constructor", - // Setters - "public-static-set", - "protected-static-set", - "private-static-set", + // Getters + "public-static-get", + "protected-static-get", + "private-static-get", - "public-decorated-set", - "protected-decorated-set", - "private-decorated-set", + "public-decorated-get", + "protected-decorated-get", + "private-decorated-get", - "public-instance-set", - "protected-instance-set", - "private-instance-set", + "public-instance-get", + "protected-instance-get", + "private-instance-get", - "public-abstract-set", - "protected-abstract-set", - "private-abstract-set", + "public-abstract-get", + "protected-abstract-get", + "private-abstract-get", - "public-set", - "protected-set", - "private-set", + "public-get", + "protected-get", + "private-get", - "static-set", - "instance-set", - "abstract-set", + "static-get", + "instance-get", + "abstract-get", - "decorated-set", + "decorated-get", - "set", + "get", - // Methods - "public-static-method", - "protected-static-method", - "private-static-method", - "public-decorated-method", - "protected-decorated-method", - "private-decorated-method", - "public-instance-method", - "protected-instance-method", - "private-instance-method", - "public-abstract-method", - "protected-abstract-method", - "private-abstract-method" -] -``` + // Setters + "public-static-set", + "protected-static-set", + "private-static-set", -:::note -If you only specify some of the possible types, the non-specified ones can have any particular order. -This means that they can be placed before, within or after the specified types and the linter won't complain about it. -::: + "public-decorated-set", + "protected-decorated-set", + "private-decorated-set", -#### Member Group Types (With Accessibility, Ignoring Scope) + "public-instance-set", + "protected-instance-set", + "private-instance-set", -It is also possible to group member types by their accessibility (`static`, `instance`, `abstract`), ignoring their scope. + "public-abstract-set", + "protected-abstract-set", + "private-abstract-set", -```jsonc -[ - // Index signature - // No accessibility for index signature. See above. + "public-set", + "protected-set", + "private-set", - // 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-set", + "instance-set", + "abstract-set", - // Constructors - // Only the accessibility of constructors is configurable. See below. + "decorated-set", - // 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"] + "set", - // 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-static-method", + "protected-static-method", + "private-static-method", - // 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"] -] -``` + "public-decorated-method", + "protected-decorated-method", + "private-decorated-method", -#### Member Group Types (With Accessibility and a Decorator) + "public-instance-method", + "protected-instance-method", + "private-instance-method", -It is also possible to group methods or fields with a decorator separately, optionally specifying -their accessibility. + "public-abstract-method", + "protected-abstract-method", + "private-abstract-method", -```jsonc -[ - // Index signature - // No decorators for index signature. + "public-method", + "protected-method", + "private-method", - // Fields - "public-decorated-field", - "protected-decorated-field", - "private-decorated-field", + "static-method", + "instance-method", + "abstract-method", - "decorated-field", // = ["public-decorated-field", "protected-decorated-field", "private-decorated-field"] + "decorated-method", - // Constructors - // There are no decorators for constructors. + "method" + ] +} +``` - // Getters - "public-decorated-get", - "protected-decorated-get", - "private-decorated-get", +:::note +The default configuration contains member group types which contain other member types. +This is intentional to provide better error messages. +::: - "decorated-get" // = ["public-decorated-get", "protected-decorated-get", "private-decorated-get"] +:::tip +By default, the members are not sorted. +If you want to sort them alphabetically, you have to provide a custom configuration. +::: - // Setters - "public-decorated-set", - "protected-decorated-set", - "private-decorated-set", +## Examples - "decorated-set" // = ["public-decorated-set", "protected-decorated-set", "private-decorated-set"] +### General Order on All Constructs - // Methods - "public-decorated-method", - "protected-decorated-method", - "private-decorated-method", +This config specifies the order for all constructs. +It ignores member types other than signatures, methods, constructors, and fields. +It also ignores accessibility and scope. - "decorated-method" // = ["public-decorated-method", "protected-decorated-method", "private-decorated-method"] -] +```jsonc +// .eslintrc.json +{ + "rules": { + "@typescript-eslint/no-non-null-assertion": [ + "error", + { "default": ["signature", "method", "constructor", "field"] } + ] + } +} ``` -#### Member Group Types (With Scope, Ignoring Accessibility) + -Another option is to group the member types by their scope (`public`, `protected`, `private`), ignoring their accessibility. - -```jsonc -[ - // Index signature - // No scope for index signature. See above. - - // 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", "private-abstract-field"] - - // 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", "private-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", "private-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", "private-abstract-method"] -] -``` - -#### Member Group Types (With Scope and Accessibility) - -The third grouping option is to ignore both scope and accessibility. - -```jsonc -[ - // Index signature - // No grouping for index signature. See above. - - // 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", private-abstract-field"] - - // Constructors - // Only the accessibility of constructors is configurable. See above. - - // 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", "private-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", "private-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", "private-abstract-method"] -] -``` - -#### Grouping Different Member Types at the Same Rank - -It is also possible to group different member types at the same rank. - -```jsonc -[ - // Index signature - "signature", - - // Fields - "field", - - // Constructors - "constructor", - - // Getters and Setters at the same rank - ["get", "set"], - - // Methods - "method" -] -``` - -
- -### Default configuration - -The default configuration looks as follows: - -```jsonc -{ - "default": [ - // Index signature - "signature", - - // Fields - "public-static-field", - "protected-static-field", - "private-static-field", - - "public-decorated-field", - "protected-decorated-field", - "private-decorated-field", - - "public-instance-field", - "protected-instance-field", - "private-instance-field", - - "public-abstract-field", - "protected-abstract-field", - "private-abstract-field", - - "public-field", - "protected-field", - "private-field", - - "static-field", - "instance-field", - "abstract-field", - - "decorated-field", - - "field", - - // Constructors - "public-constructor", - "protected-constructor", - "private-constructor", - - "constructor", - - // Getters - "public-static-get", - "protected-static-get", - "private-static-get", - - "public-decorated-get", - "protected-decorated-get", - "private-decorated-get", - - "public-instance-get", - "protected-instance-get", - "private-instance-get", - - "public-abstract-get", - "protected-abstract-get", - "private-abstract-get", - - "public-get", - "protected-get", - "private-get", - - "static-get", - "instance-get", - "abstract-get", - - "decorated-get", - - "get", - - // Setters - "public-static-set", - "protected-static-set", - "private-static-set", - - "public-decorated-set", - "protected-decorated-set", - "private-decorated-set", - - "public-instance-set", - "protected-instance-set", - "private-instance-set", - - "public-abstract-set", - "protected-abstract-set", - "private-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", - - "public-decorated-method", - "protected-decorated-method", - "private-decorated-method", - - "public-instance-method", - "protected-instance-method", - "private-instance-method", - - "public-abstract-method", - "protected-abstract-method", - "private-abstract-method", - - "public-method", - "protected-method", - "private-method", - - "static-method", - "instance-method", - "abstract-method", - - "decorated-method", - - "method" - ] -} -``` - -:::note -The default configuration contains member group types which contain other member types (see above). This is intentional to provide better error messages. -::: - -:::tip -By default, the members are not sorted. If you want to sort them alphabetically, you have to provide a custom configuration. -::: - -## Examples - -### General Order on All Constructs - -This config specifies the order for all constructs. -It ignores member types other than signatures, methods, constructors, and fields. -It also ignores accessibility and scope. - -```jsonc -// .eslintrc.json -{ - "rules": { - "@typescript-eslint/no-non-null-assertion": [ - "error", - { "default": ["signature", "method", "constructor", "field"] } - ] - } -} -``` - - - -#### ❌ Incorrect +#### ❌ Incorrect ```ts interface Foo { @@ -1156,6 +882,280 @@ interface Foo { } ``` +## All Supported Options + +### Member Types (Granular Form) + +There are multiple ways to specify the member types. +The most explicit and granular form is the following: + +```jsonc +[ + // Index signature + "signature", + + // Fields + "public-static-field", + "protected-static-field", + "private-static-field", + "public-decorated-field", + "protected-decorated-field", + "private-decorated-field", + "public-instance-field", + "protected-instance-field", + "private-instance-field", + "public-abstract-field", + "protected-abstract-field", + "private-abstract-field", + + // Constructors + "public-constructor", + "protected-constructor", + "private-constructor", + + // Getters + "public-static-get", + "protected-static-get", + "private-static-get", + + "public-decorated-get", + "protected-decorated-get", + "private-decorated-get", + + "public-instance-get", + "protected-instance-get", + "private-instance-get", + + "public-abstract-get", + "protected-abstract-get", + "private-abstract-get", + + "public-get", + "protected-get", + "private-get", + + "static-get", + "instance-get", + "abstract-get", + + "decorated-get", + + "get", + + // Setters + "public-static-set", + "protected-static-set", + "private-static-set", + + "public-decorated-set", + "protected-decorated-set", + "private-decorated-set", + + "public-instance-set", + "protected-instance-set", + "private-instance-set", + + "public-abstract-set", + "protected-abstract-set", + "private-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", + "public-decorated-method", + "protected-decorated-method", + "private-decorated-method", + "public-instance-method", + "protected-instance-method", + "private-instance-method", + "public-abstract-method", + "protected-abstract-method", + "private-abstract-method" +] +``` + +:::note +If you only specify some of the possible types, the non-specified ones can have any particular order. +This means that they can be placed before, within or after the specified types and the linter won't complain about it. +::: + +### Member Group Types (With Accessibility, Ignoring Scope) + +It is also possible to group member types by their accessibility (`static`, `instance`, `abstract`), ignoring their scope. + +```jsonc +[ + // 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"] + + // 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"] +] +``` + +### Member Group Types (With Accessibility and a Decorator) + +It is also possible to group methods or fields with a decorator separately, optionally specifying +their accessibility. + +```jsonc +[ + // 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"] + + // 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"] +] +``` + +### Member Group Types (With Scope, Ignoring Accessibility) + +Another option is to group the member types by their scope (`public`, `protected`, `private`), ignoring their accessibility. + +```jsonc +[ + // 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", "private-abstract-field"] + + // 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", "private-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", "private-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", "private-abstract-method"] +] +``` + +### Member Group Types (With Scope and Accessibility) + +The third grouping option is to ignore both scope and accessibility. + +```jsonc +[ + // 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", private-abstract-field"] + + // 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", "private-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", "private-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", "private-abstract-method"] +] +``` + +### Grouping Different Member Types at the Same Rank + +It is also possible to group different member types at the same rank. + +```jsonc +[ + // Index signature + "signature", + + // Fields + "field", + + // Constructors + "constructor", + + // Getters and Setters at the same rank + ["get", "set"], + + // Methods + "method" +] +``` + ## When Not To Use It If you don't care about the general order of your members, then you will not need this rule.