Skip to content

Commit 9f82099

Browse files
a-tarasyukJamesHenry
authored andcommittedAug 19, 2019
feat(eslint-plugin): add quotes [extension] (#762)
1 parent 656d255 commit 9f82099

File tree

8 files changed

+772
-0
lines changed

8 files changed

+772
-0
lines changed
 

‎packages/eslint-plugin/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ Then you should add `airbnb` (or `airbnb-base`) to your `extends` section of `.e
191191
| [`@typescript-eslint/prefer-regexp-exec`](./docs/rules/prefer-regexp-exec.md) | Prefer RegExp#exec() over String#match() if no global flag is provided | :heavy_check_mark: | | :thought_balloon: |
192192
| [`@typescript-eslint/prefer-string-starts-ends-with`](./docs/rules/prefer-string-starts-ends-with.md) | Enforce the use of `String#startsWith` and `String#endsWith` instead of other equivalent methods of checking substrings | :heavy_check_mark: | :wrench: | :thought_balloon: |
193193
| [`@typescript-eslint/promise-function-async`](./docs/rules/promise-function-async.md) | Requires any function or method that returns a Promise to be marked async | | | :thought_balloon: |
194+
| [`@typescript-eslint/quotes`](./docs/rules/quotes.md) | Enforce the consistent use of either backticks, double, or single quotes | | :wrench: | |
194195
| [`@typescript-eslint/require-array-sort-compare`](./docs/rules/require-array-sort-compare.md) | Enforce giving `compare` argument to `Array#sort` | | | :thought_balloon: |
195196
| [`@typescript-eslint/require-await`](./docs/rules/require-await.md) | Disallow async functions which have no `await` expression | :heavy_check_mark: | | :thought_balloon: |
196197
| [`@typescript-eslint/restrict-plus-operands`](./docs/rules/restrict-plus-operands.md) | When adding two variables, operands must both be of type number or of type string | | | :thought_balloon: |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Enforce the consistent use of either backticks, double, or single quotes
2+
3+
## Rule Details
4+
5+
This rule extends the base [eslint/quotes](https://eslint.org/docs/rules/quotes) rule.
6+
It supports all options and features of the base rule.
7+
8+
## How to use
9+
10+
```cjson
11+
{
12+
// note you must disable the base rule as it can report incorrect errors
13+
"quotes": "off",
14+
"@typescript-eslint/quotes": ["error"]
15+
}
16+
```
17+
18+
## Options
19+
20+
See [eslint/quotes options](https://eslint.org/docs/rules/quotes#options).
21+
22+
<sup>Taken with ❤️ [from ESLint core](https://github.com/eslint/eslint/blob/master/docs/rules/quotes.md)</sup>

‎packages/eslint-plugin/src/configs/all.json

+2
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@
6262
"@typescript-eslint/prefer-regexp-exec": "error",
6363
"@typescript-eslint/prefer-string-starts-ends-with": "error",
6464
"@typescript-eslint/promise-function-async": "error",
65+
"quotes": "off",
66+
"@typescript-eslint/quotes": "error",
6567
"@typescript-eslint/require-array-sort-compare": "error",
6668
"require-await": "off",
6769
"@typescript-eslint/require-await": "error",

‎packages/eslint-plugin/src/rules/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import preferReadonly from './prefer-readonly';
4848
import preferRegexpExec from './prefer-regexp-exec';
4949
import preferStringStartsEndsWith from './prefer-string-starts-ends-with';
5050
import promiseFunctionAsync from './promise-function-async';
51+
import quotes from './quotes';
5152
import requireArraySortCompare from './require-array-sort-compare';
5253
import requireAwait from './require-await';
5354
import restrictPlusOperands from './restrict-plus-operands';
@@ -112,6 +113,7 @@ export default {
112113
'prefer-regexp-exec': preferRegexpExec,
113114
'prefer-string-starts-ends-with': preferStringStartsEndsWith,
114115
'promise-function-async': promiseFunctionAsync,
116+
quotes: quotes,
115117
'require-array-sort-compare': requireArraySortCompare,
116118
'require-await': requireAwait,
117119
'restrict-plus-operands': restrictPlusOperands,
+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import {
2+
AST_NODE_TYPES,
3+
TSESTree,
4+
} from '@typescript-eslint/experimental-utils';
5+
import baseRule from 'eslint/lib/rules/quotes';
6+
import * as util from '../util';
7+
8+
export type Options = util.InferOptionsTypeFromRule<typeof baseRule>;
9+
export type MessageIds = util.InferMessageIdsTypeFromRule<typeof baseRule>;
10+
11+
export default util.createRule<Options, MessageIds>({
12+
name: 'quotes',
13+
meta: {
14+
type: 'layout',
15+
docs: {
16+
description:
17+
'Enforce the consistent use of either backticks, double, or single quotes',
18+
category: 'Stylistic Issues',
19+
recommended: false,
20+
},
21+
fixable: 'code',
22+
messages: baseRule.meta.messages,
23+
schema: baseRule.meta.schema,
24+
},
25+
defaultOptions: [
26+
'double',
27+
{
28+
allowTemplateLiterals: false,
29+
avoidEscape: false,
30+
},
31+
],
32+
create(context, [option]) {
33+
const rules = baseRule.create(context);
34+
35+
const isModuleDeclaration = (node: TSESTree.Literal): boolean => {
36+
return (
37+
!!node.parent && node.parent.type === AST_NODE_TYPES.TSModuleDeclaration
38+
);
39+
};
40+
41+
const isTypeLiteral = (node: TSESTree.Literal): boolean => {
42+
return !!node.parent && node.parent.type === AST_NODE_TYPES.TSLiteralType;
43+
};
44+
45+
return {
46+
Literal(node) {
47+
if (
48+
option === 'backtick' &&
49+
(isModuleDeclaration(node) || isTypeLiteral(node))
50+
) {
51+
return;
52+
}
53+
54+
rules.Literal(node);
55+
},
56+
57+
TemplateLiteral(node) {
58+
rules.TemplateLiteral(node);
59+
},
60+
};
61+
},
62+
});

‎packages/eslint-plugin/tests/rules/quotes.test.ts

+662
Large diffs are not rendered by default.

‎packages/eslint-plugin/tools/generate-configs.ts

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const BASE_RULES_TO_BE_OVERRIDDEN = new Set([
2929
'no-empty-function',
3030
'no-extra-parens',
3131
'no-magic-numbers',
32+
'quotes',
3233
'no-unused-vars',
3334
'no-use-before-define',
3435
'no-useless-constructor',

‎packages/eslint-plugin/typings/eslint-rules.d.ts

+20
Original file line numberDiff line numberDiff line change
@@ -461,3 +461,23 @@ declare module 'eslint/lib/rules/semi' {
461461
>;
462462
export = rule;
463463
}
464+
465+
declare module 'eslint/lib/rules/quotes' {
466+
import { TSESLint, TSESTree } from '@typescript-eslint/experimental-utils';
467+
468+
const rule: TSESLint.RuleModule<
469+
never,
470+
[
471+
'single' | 'double' | 'backtick',
472+
{
473+
allowTemplateLiterals?: boolean;
474+
avoidEscape?: boolean;
475+
}?,
476+
],
477+
{
478+
Literal(node: TSESTree.Literal): void;
479+
TemplateLiteral(node: TSESTree.TemplateLiteral): void;
480+
}
481+
>;
482+
export = rule;
483+
}

0 commit comments

Comments
 (0)
Please sign in to comment.