Skip to content
This repository was archived by the owner on Jan 19, 2019. It is now read-only.

Commit

Permalink
[FEAT][BREAKING][1/2][member-delimiter-style] Better handling for sin…
Browse files Browse the repository at this point in the history
…gle line (#203)

This PR adds better handling for single line delimiters, and better enforces the `requrieLast` option.

Fixes #92

## Single line delimiters

Previously single line delimiters were either checked or not. This meant that if you used
```
{
    delimiter: "none",
    ignoreSingleLine: false,
}
```
then the fixer would break your code by removing the delimiter from single line statements i.e.:
```TS
interface Foo { bar: string, baz: number }
// fixed to this broken line
interface Foo { bar: string baz: number }
```

### Breaking change:
- Removed option `ignoreSingleLine`
- Added option `singleLine: "none" | "semi" | "comma"`

`singleLine` works the same as `delimiter`, except for single line statements only.

## Stricter `requireLast`

Previously `requireLast` did nothing when turned off, and enforced having a delimiter when turned on.

I felt this was inconsistent with the goals of the linter; being a tool to provide consistent coding conventions.

This is the first of two changes to bring the option into line with eslint's [`comma-dangle`](https://eslint.org/docs/rules/comma-dangle#options). (The next change will replace the boolean with an enum; I didn't want to overload this PR).

### Breaking change:
- `requireLast: false` now enforces that there is no delimiter on the last member.
  • Loading branch information
bradzacher authored Dec 11, 2018
1 parent be72d06 commit ecf9cb0
Show file tree
Hide file tree
Showing 3 changed files with 474 additions and 392 deletions.
96 changes: 64 additions & 32 deletions docs/rules/member-delimiter-style.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,25 @@ Enforces a consistent member delimiter style in interfaces and type literals. Th
```ts
interface Foo {
name: string;
greet(): void; // last semicolon can be ignored
greet(): void;
}

type Bar = {
name: string;
greet(): void; // last semicolon can be ignored
greet(): void;
}
```
- Comma style (JSON style).
```ts
interface Foo {
name: string,
greet(): void, // last comma can be ignored
greet(): void,
}

type Bar = {
name: string,
greet(): void, // last comma can be ignored
greet(): void,
}
```
Expand All @@ -40,7 +40,8 @@ type Bar = {
}
```
The rule also enforces the presence of the delimiter in the last member of the interface and/or type literal, allowing single line declarations to be ignored.
The rule also enforces the presence (or absence) of the delimiter in the last member of the interface and/or type literal.
Finally, this rule can enforce separate delimiter syntax for single line declarations.
## Rule Details
Expand All @@ -58,13 +59,16 @@ The rule can also take one or more of the following options:
- `"delimiter": "none"`, use this to require a linebreak.
- `"requireLast": true`, (default) use this to require a delimiter for all members of the interface and/or type literal.
- `"requireLast": false`, use this to ignore the last member of the interface and/or type literal.
- `"ignoreSingleLine": true`, (default) use this to override the `requireLast` in single line declarations.
- `"ignoreSingleLine": false`, use this to enfore the `requireLast` in single line declarations.
- `"singleLine": "semi"`, (default) use this to require a semicolon in single line declarations.
- `"singleLine": "comma"`, use this to require a comma in single line declarations.
- `"singleLine": "none"`, use this to require a linebreak (i.e. disallow mulit prop, single line declarations).
- `"overrides"`, overrides the default options for **interfaces** and **type literals**.
*Note that `delimiter` and `singleLine` are independent options - if you don't provide a value for either they will use their default option.*
### defaults
Examples of **incorrect** code for this rule with the defaults
`{ delimiter: "semi", requireLast: true, ignoreSingleLine: true }` or no option at all:
`{ delimiter: "semi", requireLast: true, singleLine: "semi" }` or no option at all:
```ts
// missing semicolon delimiter
interface Foo {
Expand Down Expand Up @@ -101,28 +105,29 @@ type Baz = {
name: string,
greet(): string
}

// incorrect delimiter
type FooBar = { name: string, greet(): string }
```
Examples of **correct** code for this rule with the default
`{ delimiter: "semi", requireLast: true, ignoreSingleLine: true }`:
`{ delimiter: "semi", requireLast: true, singleLine: "semi" }`:
```ts
interface Foo {
name: string;
greet(): string;
}

interface Foo { name: string }

interface Foo { name: string; }

type Bar = {
name: string;
greet(): string;
}

type Bar = { name: string }

type Bar = { name: string; }

type FooBar = { name: string; greet(): string; }
```
### delimiter - semi
Expand All @@ -143,12 +148,11 @@ interface Bar {

Examples of **correct** code for this rule with `{ delimiter: "semi" }`:
```ts
// with requireLast = true/false
// with requireLast = true
interface Foo {
name: string;
greet(): string;
}

type Bar = {
name: string;
greet(): string;
Expand All @@ -159,7 +163,6 @@ interface Foo {
name: string;
greet(): string
}

type Bar = {
name: string;
greet(): string
Expand All @@ -184,12 +187,11 @@ interface Bar {

Examples of **correct** code for this rule with `{ delimiter: "comma" }`:
```ts
// with requireLast = true/false
// with requireLast = true
interface Foo {
name: string,
greet(): string,
}

type Bar = {
name: string,
greet(): string,
Expand Down Expand Up @@ -299,42 +301,72 @@ type Baz = {
```
### ignoreSingleLine
Examples of **incorrect** code for this rule with `{ ignoreSingleLine: true }`:
Examples of **incorrect** code for this rule with `{ singleLine: "semi" }`:
```ts
// using incorrect delimiter
interface Foo { name: string, }
interface Foo { name: string, greet(): string, }

// using incorrect delimiter
type Bar = { name: string, }
type Bar = { name: string, greet(): string, }
```
Examples of **correct** code for this rule with `{ ignoreSingleLine: true }`:
Examples of **correct** code for this rule with `{ singleLine: "semi" }`:
```ts
// can have a delimiter or not
interface Foo { name: string }

interface Foo { name: string; }
interface Foo { name: string; greet(): string; }

// can have a delimiter or not
type Bar = { name: string }
type Bar = { name: string; }
type Bar = { name: string; greet(): string; }
```
Examples of **incorrect** code for this rule with `{ singleLine: "comma" }`:
```ts
// using incorrect delimiter
interface Foo { name: string; }
interface Foo { name: string; greet(): string; }

type Bar = { name: string; }
type Bar = { name: string; greet(): string; }
```
Examples of **incorrect** code for this rule with `{ ignoreSingleLine: false }`:
Examples of **correct** code for this rule with `{ singleLine: "comma" }`:
```ts
// missing delimiter
interface Foo { name: string }
interface Foo { name: string, }
interface Foo { name: string, greet(): string, }

// missing delimiter
type Bar = { name: string }
type Bar = { name: string, }
type Bar = { name: string, greet(): string, }
```
Examples of **correct** code for this rule with `{ ignoreSingleLine: false }`:
Examples of **incorrect** code for this rule with `{ singleLine: "none" }`:
```ts
// has a delimiter when it shouldn't
interface Foo { name: string; }
interface Foo { name: string; greet(): string; }
interface Foo { name: string, }
interface Foo { name: string, greet(): string, }

type Bar = { name: string; }
type Bar = { name: string; greet(): string; }
type Bar = { name: string, }
type Bar = { name: string, greet(): string, }
```
Examples of **correct** code for this rule with `{ singleLine: "none" }`:
```ts
interface Foo { name: string }
type Bar = { name: string }

// Note that there is no syntax-valid way to do types single-line without a delimiter
interface Foo {
name: string
greet(): string
}
type Bar = {
name: string
greet(): string
}
```
### overrides - interface
Expand Down
Loading

0 comments on commit ecf9cb0

Please sign in to comment.