Skip to content

Commit 32753d1

Browse files
bradzacherJamesHenry
authored andcommitted
[FEAT] Recommended config (typescript-eslint#261)
Fixes typescript-eslint#144 Requires ~~typescript-eslint#259~~, ~~typescript-eslint#260~~. - added a util to make it standardised and easier to add default config for a rule - configured recommended based on typescript-eslint#144 - purposely switched `recommended` prop to be `"error" | "warning" | false` - inside the eslint repo, it should be `true`. otherwise it's just a property that isn't used officially by eslint. It's truthy so `eslint-docs` still work. - changed recommended generator to accept `"error"`/`"warning"` for more configurability. - adjusted default config of certain rules that didn't match our recommendations.
1 parent 8229d06 commit 32753d1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+709
-209
lines changed

Diff for: packages/eslint-plugin-typescript/.prettierignore

+2
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
node_modules
2+
lib/configs/recommended.json
3+
.vscode

Diff for: packages/eslint-plugin-typescript/.vscode/launch.json

+8
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@
1717
],
1818
"console": "integratedTerminal",
1919
"internalConsoleOptions": "neverOpen"
20+
},
21+
{
22+
"type": "node",
23+
"request": "launch",
24+
"name": "update-recommended.js",
25+
"args": [
26+
"${workspaceFolder}/tools/update-recommended.js"
27+
]
2028
}
2129
]
2230
}

Diff for: packages/eslint-plugin-typescript/README.md

+37-27
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ $ npm install eslint-plugin-typescript --save-dev
2626

2727
## Usage
2828

29-
Add `eslint-plugin-typescript/parser` to the `parser` field and `typescript` to the plugins section of your `.eslintrc` configuration file. You can omit the `eslint-plugin-` prefix:
29+
Add `eslint-plugin-typescript/parser` to the `parser` field and `typescript` to the plugins section of your `.eslintrc` configuration file:
3030

3131
```json
3232
{
@@ -35,18 +35,28 @@ Add `eslint-plugin-typescript/parser` to the `parser` field and `typescript` to
3535
}
3636
```
3737

38+
Note: The plugin provides its own version of the `typescript-eslint-parser` via `eslint-plugin-typescript/parser`.
39+
This helps us guarantee 100% compatibility between the plugin and the parser.
40+
3841
Then configure the rules you want to use under the rules section.
3942

4043
```json
4144
{
45+
"parser": "eslint-plugin-typescript/parser",
46+
"plugins": ["typescript"],
4247
"rules": {
4348
"typescript/rule-name": "error"
4449
}
4550
}
4651
```
4752

48-
Note: The plugin provides its own version of the `typescript-eslint-parser` via `eslint-plugin-typescript/parser`.
49-
This guarantees 100% compatibility between the plugin and the parser.
53+
You can also enable all the recommended rules at once. Add `plugin:typescript/recommended` in extends:
54+
55+
```json
56+
{
57+
"extends": ["plugin:typescript/recommended"]
58+
}
59+
```
5060

5161
## Supported Rules
5262

@@ -58,38 +68,38 @@ This guarantees 100% compatibility between the plugin and the parser.
5868
<!-- prettier-ignore -->
5969
| Name | Description | :heavy_check_mark: | :wrench: |
6070
| ---- | ----------- | ------------------ | -------- |
61-
| [`typescript/adjacent-overload-signatures`](./docs/rules/adjacent-overload-signatures.md) | Require that member overloads be consecutive (`adjacent-overload-signatures` from TSLint) | | |
62-
| [`typescript/array-type`](./docs/rules/array-type.md) | Requires using either `T[]` or `Array<T>` for arrays (`array-type` from TSLint) | | :wrench: |
63-
| [`typescript/ban-types`](./docs/rules/ban-types.md) | Enforces that types will not to be used (`ban-types` from TSLint) | | :wrench: |
64-
| [`typescript/camelcase`](./docs/rules/camelcase.md) | Enforce camelCase naming convention | | |
71+
| [`typescript/adjacent-overload-signatures`](./docs/rules/adjacent-overload-signatures.md) | Require that member overloads be consecutive (`adjacent-overload-signatures` from TSLint) | :heavy_check_mark: | |
72+
| [`typescript/array-type`](./docs/rules/array-type.md) | Requires using either `T[]` or `Array<T>` for arrays (`array-type` from TSLint) | :heavy_check_mark: | :wrench: |
73+
| [`typescript/ban-types`](./docs/rules/ban-types.md) | Enforces that types will not to be used (`ban-types` from TSLint) | :heavy_check_mark: | :wrench: |
74+
| [`typescript/camelcase`](./docs/rules/camelcase.md) | Enforce camelCase naming convention | :heavy_check_mark: | |
6575
| [`typescript/class-name-casing`](./docs/rules/class-name-casing.md) | Require PascalCased class and interface names (`class-name` from TSLint) | :heavy_check_mark: | |
66-
| [`typescript/explicit-function-return-type`](./docs/rules/explicit-function-return-type.md) | Require explicit return types on functions and class methods | | |
67-
| [`typescript/explicit-member-accessibility`](./docs/rules/explicit-member-accessibility.md) | Require explicit accessibility modifiers on class properties and methods (`member-access` from TSLint) | | |
76+
| [`typescript/explicit-function-return-type`](./docs/rules/explicit-function-return-type.md) | Require explicit return types on functions and class methods | :heavy_check_mark: | |
77+
| [`typescript/explicit-member-accessibility`](./docs/rules/explicit-member-accessibility.md) | Require explicit accessibility modifiers on class properties and methods (`member-access` from TSLint) | :heavy_check_mark: | |
6878
| [`typescript/generic-type-naming`](./docs/rules/generic-type-naming.md) | Enforces naming of generic type variables | | |
6979
| [`typescript/indent`](./docs/rules/indent.md) | Enforce consistent indentation (`indent` from TSLint) | :heavy_check_mark: | :wrench: |
70-
| [`typescript/interface-name-prefix`](./docs/rules/interface-name-prefix.md) | Require that interface names be prefixed with `I` (`interface-name` from TSLint) | | |
71-
| [`typescript/member-delimiter-style`](./docs/rules/member-delimiter-style.md) | Require a specific member delimiter style for interfaces and type literals | | :wrench: |
80+
| [`typescript/interface-name-prefix`](./docs/rules/interface-name-prefix.md) | Require that interface names be prefixed with `I` (`interface-name` from TSLint) | :heavy_check_mark: | |
81+
| [`typescript/member-delimiter-style`](./docs/rules/member-delimiter-style.md) | Require a specific member delimiter style for interfaces and type literals | :heavy_check_mark: | :wrench: |
7282
| [`typescript/member-naming`](./docs/rules/member-naming.md) | Enforces naming conventions for class members by visibility. | | |
7383
| [`typescript/member-ordering`](./docs/rules/member-ordering.md) | Require a consistent member declaration order (`member-ordering` from TSLint) | | |
74-
| [`typescript/no-angle-bracket-type-assertion`](./docs/rules/no-angle-bracket-type-assertion.md) | Enforces the use of `as Type` assertions instead of `<Type>` assertions (`no-angle-bracket-type-assertion` from TSLint) | | |
75-
| [`typescript/no-array-constructor`](./docs/rules/no-array-constructor.md) | Disallow generic `Array` constructors | | :wrench: |
76-
| [`typescript/no-empty-interface`](./docs/rules/no-empty-interface.md) | Disallow the declaration of empty interfaces (`no-empty-interface` from TSLint) | | |
77-
| [`typescript/no-explicit-any`](./docs/rules/no-explicit-any.md) | Disallow usage of the `any` type (`no-any` from TSLint) | | |
84+
| [`typescript/no-angle-bracket-type-assertion`](./docs/rules/no-angle-bracket-type-assertion.md) | Enforces the use of `as Type` assertions instead of `<Type>` assertions (`no-angle-bracket-type-assertion` from TSLint) | :heavy_check_mark: | |
85+
| [`typescript/no-array-constructor`](./docs/rules/no-array-constructor.md) | Disallow generic `Array` constructors | :heavy_check_mark: | :wrench: |
86+
| [`typescript/no-empty-interface`](./docs/rules/no-empty-interface.md) | Disallow the declaration of empty interfaces (`no-empty-interface` from TSLint) | :heavy_check_mark: | |
87+
| [`typescript/no-explicit-any`](./docs/rules/no-explicit-any.md) | Disallow usage of the `any` type (`no-any` from TSLint) | :heavy_check_mark: | |
7888
| [`typescript/no-extraneous-class`](./docs/rules/no-extraneous-class.md) | Forbids the use of classes as namespaces (`no-unnecessary-class` from TSLint) | | |
79-
| [`typescript/no-inferrable-types`](./docs/rules/no-inferrable-types.md) | Disallows explicit type declarations for variables or parameters initialized to a number, string, or boolean. (`no-inferrable-types` from TSLint) | | :wrench: |
80-
| [`typescript/no-misused-new`](./docs/rules/no-misused-new.md) | Enforce valid definition of `new` and `constructor`. (`no-misused-new` from TSLint) | | |
81-
| [`typescript/no-namespace`](./docs/rules/no-namespace.md) | Disallow the use of custom TypeScript modules and namespaces (`no-namespace` from TSLint) | | |
82-
| [`typescript/no-non-null-assertion`](./docs/rules/no-non-null-assertion.md) | Disallows non-null assertions using the `!` postfix operator (`no-non-null-assertion` from TSLint) | | |
83-
| [`typescript/no-object-literal-type-assertion`](./docs/rules/no-object-literal-type-assertion.md) | Forbids an object literal to appear in a type assertion expression (`no-object-literal-type-assertion` from TSLint) | | |
84-
| [`typescript/no-parameter-properties`](./docs/rules/no-parameter-properties.md) | Disallow the use of parameter properties in class constructors. (`no-parameter-properties` from TSLint) | | |
89+
| [`typescript/no-inferrable-types`](./docs/rules/no-inferrable-types.md) | Disallows explicit type declarations for variables or parameters initialized to a number, string, or boolean. (`no-inferrable-types` from TSLint) | :heavy_check_mark: | :wrench: |
90+
| [`typescript/no-misused-new`](./docs/rules/no-misused-new.md) | Enforce valid definition of `new` and `constructor`. (`no-misused-new` from TSLint) | :heavy_check_mark: | |
91+
| [`typescript/no-namespace`](./docs/rules/no-namespace.md) | Disallow the use of custom TypeScript modules and namespaces (`no-namespace` from TSLint) | :heavy_check_mark: | |
92+
| [`typescript/no-non-null-assertion`](./docs/rules/no-non-null-assertion.md) | Disallows non-null assertions using the `!` postfix operator (`no-non-null-assertion` from TSLint) | :heavy_check_mark: | |
93+
| [`typescript/no-object-literal-type-assertion`](./docs/rules/no-object-literal-type-assertion.md) | Forbids an object literal to appear in a type assertion expression (`no-object-literal-type-assertion` from TSLint) | :heavy_check_mark: | |
94+
| [`typescript/no-parameter-properties`](./docs/rules/no-parameter-properties.md) | Disallow the use of parameter properties in class constructors. (`no-parameter-properties` from TSLint) | :heavy_check_mark: | |
8595
| [`typescript/no-this-alias`](./docs/rules/no-this-alias.md) | Disallow aliasing `this` (`no-this-assignment` from TSLint) | | |
86-
| [`typescript/no-triple-slash-reference`](./docs/rules/no-triple-slash-reference.md) | Disallow `/// <reference path="" />` comments (`no-reference` from TSLint) | | |
96+
| [`typescript/no-triple-slash-reference`](./docs/rules/no-triple-slash-reference.md) | Disallow `/// <reference path="" />` comments (`no-reference` from TSLint) | :heavy_check_mark: | |
8797
| [`typescript/no-type-alias`](./docs/rules/no-type-alias.md) | Disallow the use of type aliases (`interface-over-type-literal` from TSLint) | | |
8898
| [`typescript/no-unused-vars`](./docs/rules/no-unused-vars.md) | Disallow unused variables (`no-unused-variable` from TSLint) | :heavy_check_mark: | |
89-
| [`typescript/no-use-before-define`](./docs/rules/no-use-before-define.md) | Disallow the use of variables before they are defined | | |
90-
| [`typescript/no-var-requires`](./docs/rules/no-var-requires.md) | Disallows the use of require statements except in import statements (`no-var-requires` from TSLint) | | |
91-
| [`typescript/prefer-interface`](./docs/rules/prefer-interface.md) | Prefer an interface declaration over a type literal (type T = { ... }) (`interface-over-type-literal` from TSLint) | | :wrench: |
92-
| [`typescript/prefer-namespace-keyword`](./docs/rules/prefer-namespace-keyword.md) | Require the use of the `namespace` keyword instead of the `module` keyword to declare custom TypeScript modules. (`no-internal-module` from TSLint) | | :wrench: |
93-
| [`typescript/type-annotation-spacing`](./docs/rules/type-annotation-spacing.md) | Require consistent spacing around type annotations (`typedef-whitespace` from TSLint) | | :wrench: |
99+
| [`typescript/no-use-before-define`](./docs/rules/no-use-before-define.md) | Disallow the use of variables before they are defined | :heavy_check_mark: | |
100+
| [`typescript/no-var-requires`](./docs/rules/no-var-requires.md) | Disallows the use of require statements except in import statements (`no-var-requires` from TSLint) | :heavy_check_mark: | |
101+
| [`typescript/prefer-interface`](./docs/rules/prefer-interface.md) | Prefer an interface declaration over a type literal (type T = { ... }) (`interface-over-type-literal` from TSLint) | :heavy_check_mark: | :wrench: |
102+
| [`typescript/prefer-namespace-keyword`](./docs/rules/prefer-namespace-keyword.md) | Require the use of the `namespace` keyword instead of the `module` keyword to declare custom TypeScript modules. (`no-internal-module` from TSLint) | :heavy_check_mark: | :wrench: |
103+
| [`typescript/type-annotation-spacing`](./docs/rules/type-annotation-spacing.md) | Require consistent spacing around type annotations (`typedef-whitespace` from TSLint) | :heavy_check_mark: | :wrench: |
94104

95105
<!-- end rule list -->

Diff for: packages/eslint-plugin-typescript/docs/rules/ban-types.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@ class Foo<F = string> extends Bar<string> implements Baz<string> {
3737
// report usages of the type using the default error message
3838
"Foo": null,
3939
40-
// add a custom message to help explain why not to use it
40+
// add a custom message to help explain why not to use it
4141
"Bar": "Don't use bar!",
4242
4343
// add a custom message, AND tell the plugin how to fix it
4444
"String": {
45-
"message": "Use string instead",
45+
"message": "Use string instead",
4646
"fixWith": "string"
4747
}
4848
}
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,42 @@
11
{
2+
"parser": "eslint-plugin-typescript/parser",
3+
"parserOptions": {
4+
"sourceType": "module"
5+
},
6+
"plugins": [
7+
"typescript"
8+
],
29
"rules": {
3-
"class-name-casing": "error",
4-
"indent": "error",
5-
"no-unused-vars": "error"
10+
"typescript/adjacent-overload-signatures": "error",
11+
"typescript/array-type": "error",
12+
"typescript/ban-types": "error",
13+
"camelcase": "off",
14+
"typescript/camelcase": "error",
15+
"typescript/class-name-casing": "error",
16+
"typescript/explicit-function-return-type": "warning",
17+
"typescript/explicit-member-accessibility": "error",
18+
"indent": "off",
19+
"typescript/indent": "error",
20+
"typescript/interface-name-prefix": "error",
21+
"typescript/member-delimiter-style": "error",
22+
"typescript/no-angle-bracket-type-assertion": "error",
23+
"no-array-constructor": "off",
24+
"typescript/no-array-constructor": "error",
25+
"typescript/no-empty-interface": "error",
26+
"typescript/no-explicit-any": "warning",
27+
"typescript/no-inferrable-types": "error",
28+
"typescript/no-misused-new": "error",
29+
"typescript/no-namespace": "error",
30+
"typescript/no-non-null-assertion": "error",
31+
"typescript/no-object-literal-type-assertion": "error",
32+
"typescript/no-parameter-properties": "error",
33+
"typescript/no-triple-slash-reference": "error",
34+
"no-unused-vars": "off",
35+
"typescript/no-unused-vars": "warning",
36+
"typescript/no-use-before-define": "error",
37+
"typescript/no-var-requires": "error",
38+
"typescript/prefer-interface": "error",
39+
"typescript/prefer-namespace-keyword": "error",
40+
"typescript/type-annotation-spacing": "error"
641
}
742
}

Diff for: packages/eslint-plugin-typescript/lib/rules/adjacent-overload-signatures.js

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ module.exports = {
1818
category: "TypeScript",
1919
extraDescription: [util.tslintRule("adjacent-overload-signatures")],
2020
url: util.metaDocsUrl("adjacent-overload-signatures"),
21+
recommended: "error",
2122
},
2223
schema: [],
2324
messages: {

Diff for: packages/eslint-plugin-typescript/lib/rules/array-type.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ function typeNeedsParentheses(node) {
7878
// Rule Definition
7979
//------------------------------------------------------------------------------
8080

81+
const defaultOptions = ["array"];
82+
8183
module.exports = {
8284
meta: {
8385
type: "suggestion",
@@ -86,6 +88,7 @@ module.exports = {
8688
extraDescription: [util.tslintRule("array-type")],
8789
category: "TypeScript",
8890
url: util.metaDocsUrl("array-type"),
91+
recommended: "error",
8992
},
9093
fixable: "code",
9194
messages: {
@@ -105,7 +108,7 @@ module.exports = {
105108
],
106109
},
107110
create(context) {
108-
const option = context.options[0] || "array";
111+
const option = util.applyDefault(defaultOptions, context.options)[0];
109112
const sourceCode = context.getSourceCode();
110113

111114
/**

Diff for: packages/eslint-plugin-typescript/lib/rules/ban-types.js

+30-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,33 @@ const util = require("../util");
1010
// Rule Definition
1111
//------------------------------------------------------------------------------
1212

13+
const defaultOptions = [
14+
{
15+
types: {
16+
String: {
17+
message: "Use string instead",
18+
fixWith: "string",
19+
},
20+
Boolean: {
21+
message: "Use boolean instead",
22+
fixWith: "boolean",
23+
},
24+
Number: {
25+
message: "Use number instead",
26+
fixWith: "number",
27+
},
28+
Object: {
29+
message: "Use Record<string, any> instead",
30+
fixWith: "Record<string, any>",
31+
},
32+
Symbol: {
33+
message: "Use symbol instead",
34+
fixWith: "symbol",
35+
},
36+
},
37+
},
38+
];
39+
1340
module.exports = {
1441
meta: {
1542
type: "suggestion",
@@ -18,6 +45,7 @@ module.exports = {
1845
extraDescription: [util.tslintRule("ban-types")],
1946
category: "TypeScript",
2047
url: util.metaDocsUrl("ban-types"),
48+
recommended: "error",
2149
},
2250
fixable: "code",
2351
messages: {
@@ -52,7 +80,8 @@ module.exports = {
5280
},
5381

5482
create(context) {
55-
const banedTypes = (context.options[0] || {}).types || {};
83+
const banedTypes = util.applyDefault(defaultOptions, context.options)[0]
84+
.types;
5685

5786
//----------------------------------------------------------------------
5887
// Public

Diff for: packages/eslint-plugin-typescript/lib/rules/camelcase.js

+11-7
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,21 @@ const util = require("../util");
1010
//------------------------------------------------------------------------------
1111
// Rule Definition
1212
//------------------------------------------------------------------------------
13+
const defaultOptions = [
14+
{
15+
allow: ["^UNSAFE_"],
16+
ignoreDestructuring: false,
17+
properties: "never",
18+
},
19+
];
1320

1421
/* eslint-disable eslint-plugin/require-meta-type */
1522
module.exports = {
1623
meta: Object.assign({}, baseRule.meta, {
1724
docs: {
1825
description: "Enforce camelCase naming convention",
1926
url: util.metaDocsUrl("ban-types"),
27+
recommended: "error",
2028
},
2129
}),
2230

@@ -29,13 +37,9 @@ module.exports = {
2937
"TSAbstractClassProperty",
3038
];
3139

32-
const options = context.options[0] || {};
33-
let properties = options.properties || "";
34-
const allow = options.allow || [];
35-
36-
if (properties !== "always" && properties !== "never") {
37-
properties = "always";
38-
}
40+
const options = util.applyDefault(defaultOptions, context.options)[0];
41+
const properties = options.properties;
42+
const allow = options.allow;
3943

4044
/**
4145
* Checks if a string contains an underscore and isn't all upper-case

Diff for: packages/eslint-plugin-typescript/lib/rules/class-name-casing.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ module.exports = {
1818
description: "Require PascalCased class and interface names",
1919
extraDescription: [util.tslintRule("class-name")],
2020
category: "Best Practices",
21-
recommended: true,
2221
url: util.metaDocsUrl("class-name-casing"),
22+
recommended: "error",
2323
},
24+
schema: [],
2425
},
2526

2627
create(context) {

0 commit comments

Comments
 (0)