Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(eslint-plugin): [member-delimiter-style] Add an option 'multilineDetection' to treat types and interfaces as single line if the last member ends on the same line as the closing bracket #2970

Merged
merged 4 commits into from Feb 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 8 additions & 1 deletion packages/eslint-plugin/docs/rules/member-delimiter-style.md
Expand Up @@ -72,6 +72,7 @@ type Config = BaseConfig & {
interface?: BaseConfig;
typeLiteral?: BaseConfig;
};
multilineDetection?: 'brackets' | 'last-member';
};
```

Expand All @@ -86,14 +87,20 @@ Default config:
"singleline": {
"delimiter": "semi",
"requireLast": false
}
},
"multilineDetection": "brackets"
}
```

`multiline` config only applies to multiline `interface`/`type` definitions.
`singleline` config only applies to single line `interface`/`type` definitions.
The two configs are entirely separate, and do not effect one another.

`multilineDetection` determines what counts as multiline

- `"brackets"` (default) any newlines in the type or interface make it multiline.
- `"last-member"` if the last member of the interface is on the same line as the last bracket, it is counted as a single line.

### `delimiter`

Accepts three values (or two for `singleline`):
Expand Down
19 changes: 17 additions & 2 deletions packages/eslint-plugin/src/rules/member-delimiter-style.ts
Expand Up @@ -21,6 +21,7 @@ type Config = BaseOptions & {
typeLiteral?: BaseOptions;
interface?: BaseOptions;
};
multilineDetection?: 'brackets' | 'last-member';
};
type Options = [Config];
type MessageIds =
Expand Down Expand Up @@ -82,6 +83,9 @@ export default util.createRule<Options, MessageIds>({
},
additionalProperties: false,
},
multilineDetection: {
enum: ['brackets', 'last-member'],
},
}),
additionalProperties: false,
},
Expand All @@ -97,6 +101,7 @@ export default util.createRule<Options, MessageIds>({
delimiter: 'semi',
requireLast: false,
},
multilineDetection: 'brackets',
},
],
create(context, [options]) {
Expand Down Expand Up @@ -215,11 +220,21 @@ export default util.createRule<Options, MessageIds>({
function checkMemberSeparatorStyle(
node: TSESTree.TSInterfaceBody | TSESTree.TSTypeLiteral,
): void {
const isSingleLine = node.loc.start.line === node.loc.end.line;

const members =
node.type === AST_NODE_TYPES.TSInterfaceBody ? node.body : node.members;

let isSingleLine = node.loc.start.line === node.loc.end.line;
if (
options.multilineDetection === 'last-member' &&
!isSingleLine &&
members.length > 0
) {
const lastMember = members[members.length - 1];
if (lastMember.loc.end.line === node.loc.end.line) {
isSingleLine = true;
}
}

const typeOpts =
node.type === AST_NODE_TYPES.TSInterfaceBody
? interfaceOptions
Expand Down
165 changes: 165 additions & 0 deletions packages/eslint-plugin/tests/rules/member-delimiter-style.test.ts
Expand Up @@ -705,6 +705,75 @@ type Bar = {
},
],
},
{
code: `
type Foo = {a: {
b: true;
}};
`,
options: [
{
multilineDetection: 'last-member',
},
],
},
`
type Foo = {a: {
b: true;
};};
`,
{
code: `
type Foo = {a: {
b: true;
};};
`,
options: [
{
multilineDetection: 'brackets',
},
],
},
{
code: `
type Foo = {
a: {
b: true;
};
};
`,
options: [
{
multilineDetection: 'last-member',
},
],
},
{
code: `
type Foo = {a: {
b: true;
};};
`,
options: [
{
singleline: { delimiter: 'semi', requireLast: true },
multilineDetection: 'last-member',
},
],
},
{
code: `
type Foo = {

};
`,
options: [
{
singleline: { delimiter: 'semi', requireLast: true },
multilineDetection: 'last-member',
},
],
},

{
code: `
Expand Down Expand Up @@ -3365,5 +3434,101 @@ type Foo = {
},
],
},
{
code: `
type Foo = {a: {
b: true;
};};
`,
output: `
type Foo = {a: {
b: true;
}};
`,
options: [
{
multilineDetection: 'last-member',
},
],
errors: [
{
messageId: 'unexpectedSemi',
line: 4,
column: 3,
},
],
},
{
code: `
type Foo = {a: {
b: true;
}};
`,
output: `
type Foo = {a: {
b: true;
};};
`,
errors: [
{
messageId: 'expectedSemi',
line: 4,
column: 2,
},
],
},
{
code: `
type Foo = {
a: {
b: true;
}
};
`,
output: `
type Foo = {
a: {
b: true;
};
};
`,
options: [
{
multilineDetection: 'last-member',
},
],
errors: [
{
messageId: 'expectedSemi',
line: 5,
column: 4,
},
],
},
{
code: `
type Foo = {a: {
b: true;
}};
`,
output: `
type Foo = {a: {
b: true;
};};
`,
options: [
{
singleline: { delimiter: 'semi', requireLast: true },
multilineDetection: 'last-member',
},
],
errors: [
{
messageId: 'expectedSemi',
line: 4,
column: 2,
},
],
},
],
});