diff --git a/packages/eslint-plugin/README.md b/packages/eslint-plugin/README.md
index e0f32686c9d..a3ce816616b 100644
--- a/packages/eslint-plugin/README.md
+++ b/packages/eslint-plugin/README.md
@@ -191,6 +191,7 @@ Then you should add `airbnb` (or `airbnb-base`) to your `extends` section of `.e
| [`@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: |
| [`@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: |
| [`@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: |
+| [`@typescript-eslint/quotes`](./docs/rules/quotes.md) | Enforce the consistent use of either backticks, double, or single quotes | | :wrench: | |
| [`@typescript-eslint/require-array-sort-compare`](./docs/rules/require-array-sort-compare.md) | Enforce giving `compare` argument to `Array#sort` | | | :thought_balloon: |
| [`@typescript-eslint/require-await`](./docs/rules/require-await.md) | Disallow async functions which have no `await` expression | :heavy_check_mark: | | :thought_balloon: |
| [`@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: |
diff --git a/packages/eslint-plugin/docs/rules/quotes.md b/packages/eslint-plugin/docs/rules/quotes.md
new file mode 100644
index 00000000000..e707a94b3d3
--- /dev/null
+++ b/packages/eslint-plugin/docs/rules/quotes.md
@@ -0,0 +1,22 @@
+# Enforce the consistent use of either backticks, double, or single quotes
+
+## Rule Details
+
+This rule extends the base [eslint/quotes](https://eslint.org/docs/rules/quotes) rule.
+It supports all options and features of the base rule.
+
+## How to use
+
+```cjson
+{
+ // note you must disable the base rule as it can report incorrect errors
+ "quotes": "off",
+ "@typescript-eslint/quotes": ["error"]
+}
+```
+
+## Options
+
+See [eslint/quotes options](https://eslint.org/docs/rules/quotes#options).
+
+Taken with ❤️ [from ESLint core](https://github.com/eslint/eslint/blob/master/docs/rules/quotes.md)
diff --git a/packages/eslint-plugin/src/configs/all.json b/packages/eslint-plugin/src/configs/all.json
index 30a7cafafb5..cce896718db 100644
--- a/packages/eslint-plugin/src/configs/all.json
+++ b/packages/eslint-plugin/src/configs/all.json
@@ -62,6 +62,8 @@
"@typescript-eslint/prefer-regexp-exec": "error",
"@typescript-eslint/prefer-string-starts-ends-with": "error",
"@typescript-eslint/promise-function-async": "error",
+ "quotes": "off",
+ "@typescript-eslint/quotes": "error",
"@typescript-eslint/require-array-sort-compare": "error",
"require-await": "off",
"@typescript-eslint/require-await": "error",
diff --git a/packages/eslint-plugin/src/rules/index.ts b/packages/eslint-plugin/src/rules/index.ts
index db155e691bf..bd39c7867e3 100644
--- a/packages/eslint-plugin/src/rules/index.ts
+++ b/packages/eslint-plugin/src/rules/index.ts
@@ -48,6 +48,7 @@ import preferReadonly from './prefer-readonly';
import preferRegexpExec from './prefer-regexp-exec';
import preferStringStartsEndsWith from './prefer-string-starts-ends-with';
import promiseFunctionAsync from './promise-function-async';
+import quotes from './quotes';
import requireArraySortCompare from './require-array-sort-compare';
import requireAwait from './require-await';
import restrictPlusOperands from './restrict-plus-operands';
@@ -112,6 +113,7 @@ export default {
'prefer-regexp-exec': preferRegexpExec,
'prefer-string-starts-ends-with': preferStringStartsEndsWith,
'promise-function-async': promiseFunctionAsync,
+ quotes: quotes,
'require-array-sort-compare': requireArraySortCompare,
'require-await': requireAwait,
'restrict-plus-operands': restrictPlusOperands,
diff --git a/packages/eslint-plugin/src/rules/quotes.ts b/packages/eslint-plugin/src/rules/quotes.ts
new file mode 100644
index 00000000000..97efc04c821
--- /dev/null
+++ b/packages/eslint-plugin/src/rules/quotes.ts
@@ -0,0 +1,62 @@
+import {
+ AST_NODE_TYPES,
+ TSESTree,
+} from '@typescript-eslint/experimental-utils';
+import baseRule from 'eslint/lib/rules/quotes';
+import * as util from '../util';
+
+export type Options = util.InferOptionsTypeFromRule;
+export type MessageIds = util.InferMessageIdsTypeFromRule;
+
+export default util.createRule({
+ name: 'quotes',
+ meta: {
+ type: 'layout',
+ docs: {
+ description:
+ 'Enforce the consistent use of either backticks, double, or single quotes',
+ category: 'Stylistic Issues',
+ recommended: false,
+ },
+ fixable: 'code',
+ messages: baseRule.meta.messages,
+ schema: baseRule.meta.schema,
+ },
+ defaultOptions: [
+ 'double',
+ {
+ allowTemplateLiterals: false,
+ avoidEscape: false,
+ },
+ ],
+ create(context, [option]) {
+ const rules = baseRule.create(context);
+
+ const isModuleDeclaration = (node: TSESTree.Literal): boolean => {
+ return (
+ !!node.parent && node.parent.type === AST_NODE_TYPES.TSModuleDeclaration
+ );
+ };
+
+ const isTypeLiteral = (node: TSESTree.Literal): boolean => {
+ return !!node.parent && node.parent.type === AST_NODE_TYPES.TSLiteralType;
+ };
+
+ return {
+ Literal(node) {
+ if (
+ option === 'backtick' &&
+ (isModuleDeclaration(node) || isTypeLiteral(node))
+ ) {
+ return;
+ }
+
+ rules.Literal(node);
+ },
+
+ TemplateLiteral(node) {
+ rules.TemplateLiteral(node);
+ },
+ };
+ },
+});
diff --git a/packages/eslint-plugin/tests/rules/quotes.test.ts b/packages/eslint-plugin/tests/rules/quotes.test.ts
new file mode 100644
index 00000000000..bec1f4b7e98
--- /dev/null
+++ b/packages/eslint-plugin/tests/rules/quotes.test.ts
@@ -0,0 +1,662 @@
+import rule from '../../src/rules/quotes';
+import { RuleTester } from '../RuleTester';
+
+const ruleTester = new RuleTester({
+ parser: '@typescript-eslint/parser',
+ parserOptions: {
+ ecmaVersion: 6,
+ sourceType: 'module',
+ ecmaFeatures: {},
+ },
+});
+
+/**
+ * the base rule `quotes` doesn't use a message id
+ */
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+const useDoubleQuote: any = {
+ message: 'Strings must use doublequote.',
+};
+
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+const useSingleQuote: any = {
+ message: 'Strings must use singlequote.',
+};
+
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+const useBacktick: any = {
+ message: 'Strings must use backtick.',
+};
+
+ruleTester.run('quotes', rule, {
+ valid: [
+ {
+ code: `declare module '*.html' {}`,
+ options: ['backtick'],
+ parserOptions: { ecmaVersion: 6 },
+ },
+ {
+ code: `
+ class A {
+ public prop: IProps['prop'];
+ }
+ `,
+ options: ['backtick'],
+ parserOptions: { ecmaVersion: 6 },
+ },
+
+ /** ESLint */
+ `var foo = "bar";`,
+ {
+ code: `var foo = 'bar';`,
+ options: ['single'],
+ },
+ {
+ code: `var foo = "bar";`,
+ options: ['double'],
+ },
+ {
+ code: `var foo = 1;`,
+ options: ['single'],
+ },
+ {
+ code: `var foo = 1;`,
+ options: ['double'],
+ },
+ {
+ code: `var foo = "'";`,
+ options: [
+ 'single',
+ {
+ avoidEscape: true,
+ },
+ ],
+ },
+ {
+ code: `var foo = '"';`,
+ options: [
+ 'double',
+ {
+ avoidEscape: true,
+ },
+ ],
+ },
+ {
+ code: `var foo = <>Hello world>;`,
+ options: ['single'],
+ parserOptions: {
+ ecmaVersion: 6,
+ ecmaFeatures: {
+ jsx: true,
+ },
+ },
+ },
+ {
+ code: `var foo = <>Hello world>;`,
+ options: ['double'],
+ parserOptions: {
+ ecmaVersion: 6,
+ ecmaFeatures: {
+ jsx: true,
+ },
+ },
+ },
+ {
+ code: `var foo = <>Hello world>;`,
+ options: [
+ 'double',
+ {
+ avoidEscape: true,
+ },
+ ],
+ parserOptions: {
+ ecmaVersion: 6,
+ ecmaFeatures: {
+ jsx: true,
+ },
+ },
+ },
+ {
+ code: `var foo = <>Hello world>;`,
+ options: ['backtick'],
+ parserOptions: {
+ ecmaVersion: 6,
+ ecmaFeatures: {
+ jsx: true,
+ },
+ },
+ },
+ {
+ code: `var foo = Hello world
;`,
+ options: ['single'],
+ parserOptions: {
+ ecmaVersion: 6,
+ ecmaFeatures: {
+ jsx: true,
+ },
+ },
+ },
+ {
+ code: `var foo = ;`,
+ options: ['single'],
+ parserOptions: {
+ ecmaVersion: 6,
+ ecmaFeatures: {
+ jsx: true,
+ },
+ },
+ },
+ {
+ code: `var foo = Hello world
;`,
+ options: ['double'],
+ parserOptions: {
+ ecmaVersion: 6,
+ ecmaFeatures: {
+ jsx: true,
+ },
+ },
+ },
+ {
+ code: `var foo = Hello world
;`,
+ options: [
+ 'double',
+ {
+ avoidEscape: true,
+ },
+ ],
+ parserOptions: {
+ ecmaVersion: 6,
+ ecmaFeatures: {
+ jsx: true,
+ },
+ },
+ },
+ {
+ code: 'var foo = `bar`;',
+ options: ['backtick'],
+ parserOptions: { ecmaVersion: 6 },
+ },
+ {
+ code: "var foo = `bar 'baz'`;",
+ options: ['backtick'],
+ parserOptions: { ecmaVersion: 6 },
+ },
+ {
+ code: 'var foo = `bar "baz"`;',
+ options: ['backtick'],
+ parserOptions: { ecmaVersion: 6 },
+ },
+ {
+ code: `var foo = 1;`,
+ options: ['backtick'],
+ },
+ {
+ code: 'var foo = "a string containing `backtick` quotes";',
+ options: [
+ 'backtick',
+ {
+ avoidEscape: true,
+ },
+ ],
+ },
+ {
+ code: `var foo = ;`,
+ options: ['backtick'],
+ parserOptions: {
+ ecmaVersion: 6,
+ ecmaFeatures: {
+ jsx: true,
+ },
+ },
+ },
+ {
+ code: `var foo = Hello world
;`,
+ options: ['backtick'],
+ parserOptions: {
+ ecmaVersion: 6,
+ ecmaFeatures: {
+ jsx: true,
+ },
+ },
+ },
+
+ // Backticks are only okay if they have substitutions, contain a line break, or are tagged
+ {
+ code: 'var foo = `back\ntick`;',
+ options: ['single'],
+ parserOptions: { ecmaVersion: 6 },
+ },
+ {
+ code: 'var foo = `back\rtick`;',
+ options: ['single'],
+ parserOptions: { ecmaVersion: 6 },
+ },
+ {
+ code: 'var foo = `back\u2028tick`;',
+ options: ['single'],
+ parserOptions: { ecmaVersion: 6 },
+ },
+ {
+ code: 'var foo = `back\u2029tick`;',
+ options: ['single'],
+ parserOptions: { ecmaVersion: 6 },
+ },
+ {
+ code: 'var foo = `back\\\\\ntick`;', // 2 backslashes followed by a newline
+ options: ['single'],
+ parserOptions: { ecmaVersion: 6 },
+ },
+ {
+ code: 'var foo = `back\\\\\\\\\ntick`;',
+ options: ['single'],
+ parserOptions: { ecmaVersion: 6 },
+ },
+ {
+ code: 'var foo = `\n`;',
+ options: ['single'],
+ parserOptions: { ecmaVersion: 6 },
+ },
+ {
+ code: 'var foo = `back${x}tick`;',
+ options: ['double'],
+ parserOptions: { ecmaVersion: 6 },
+ },
+ {
+ code: 'var foo = tag`backtick`;',
+ options: ['double'],
+ parserOptions: { ecmaVersion: 6 },
+ },
+
+ // Backticks are also okay if allowTemplateLiterals
+ {
+ code: "var foo = `bar 'foo' baz` + 'bar';",
+ options: [
+ 'single',
+ {
+ allowTemplateLiterals: true,
+ },
+ ],
+ parserOptions: { ecmaVersion: 6 },
+ },
+ {
+ code: 'var foo = `bar \'foo\' baz` + "bar";',
+ options: [
+ 'double',
+ {
+ allowTemplateLiterals: true,
+ },
+ ],
+ parserOptions: { ecmaVersion: 6 },
+ },
+ {
+ code: "var foo = `bar 'foo' baz` + `bar`;",
+ options: [
+ 'backtick',
+ {
+ allowTemplateLiterals: true,
+ },
+ ],
+ parserOptions: { ecmaVersion: 6 },
+ },
+
+ // `backtick` should not warn the directive prologues.
+ {
+ code: '"use strict"; var foo = `backtick`;',
+ options: ['backtick'],
+ parserOptions: { ecmaVersion: 6 },
+ },
+ {
+ code: '"use strict"; \'use strong\'; "use asm"; var foo = `backtick`;',
+ options: ['backtick'],
+ parserOptions: { ecmaVersion: 6 },
+ },
+ {
+ code:
+ 'function foo() { "use strict"; "use strong"; "use asm"; var foo = `backtick`; }',
+ options: ['backtick'],
+ parserOptions: { ecmaVersion: 6 },
+ },
+ {
+ code:
+ "(function() { 'use strict'; 'use strong'; 'use asm'; var foo = `backtick`; })();",
+ options: ['backtick'],
+ parserOptions: { ecmaVersion: 6 },
+ },
+ {
+ code:
+ '(() => { "use strict"; "use strong"; "use asm"; var foo = `backtick`; })();',
+ options: ['backtick'],
+ parserOptions: { ecmaVersion: 6 },
+ },
+
+ // `backtick` should not warn import/export sources.
+ {
+ code: `import "a"; import 'b';`,
+ options: ['backtick'],
+ parserOptions: {
+ ecmaVersion: 6,
+ sourceType: 'module',
+ },
+ },
+ {
+ code: `import a from "a"; import b from 'b';`,
+ options: ['backtick'],
+ parserOptions: {
+ ecmaVersion: 6,
+ sourceType: 'module',
+ },
+ },
+ {
+ code: `export * from "a"; export * from 'b';`,
+ options: ['backtick'],
+ parserOptions: {
+ ecmaVersion: 6,
+ sourceType: 'module',
+ },
+ },
+
+ // `backtick` should not warn property/method names (not computed).
+ {
+ code: `var obj = {"key0": 0, 'key1': 1};`,
+ options: ['backtick'],
+ parserOptions: { ecmaVersion: 6 },
+ },
+ {
+ code: `class Foo { 'bar'(){} }`,
+ options: ['backtick'],
+ parserOptions: { ecmaVersion: 6 },
+ },
+ {
+ code: `class Foo { static ''(){} }`,
+ options: ['backtick'],
+ parserOptions: { ecmaVersion: 6 },
+ },
+ ],
+
+ invalid: [
+ {
+ code: `var foo = 'bar';`,
+ output: `var foo = "bar";`,
+ errors: [useDoubleQuote],
+ },
+ {
+ code: `var foo = "bar";`,
+ output: `var foo = 'bar';`,
+ options: ['single'],
+ errors: [useSingleQuote],
+ },
+ {
+ code: 'var foo = `bar`;',
+ output: `var foo = 'bar';`,
+ options: ['single'],
+ parserOptions: { ecmaVersion: 6 },
+ errors: [useSingleQuote],
+ },
+ {
+ code: `var foo = 'don\\'t';`,
+ output: `var foo = "don't";`,
+ errors: [useDoubleQuote],
+ },
+ {
+ code: `var msg = "Plugin '" + name + "' not found"`,
+ output: `var msg = 'Plugin \\'' + name + '\\' not found'`,
+ options: ['single'],
+ errors: [
+ { ...useSingleQuote, column: 11 },
+ { ...useSingleQuote, column: 31 },
+ ],
+ },
+ {
+ code: `var foo = 'bar';`,
+ output: `var foo = "bar";`,
+ options: ['double'],
+ errors: [useDoubleQuote],
+ },
+ {
+ code: 'var foo = `bar`;',
+ output: `var foo = "bar";`,
+ options: ['double'],
+ parserOptions: { ecmaVersion: 6 },
+ errors: [useDoubleQuote],
+ },
+ {
+ code: `var foo = "bar";`,
+ output: `var foo = 'bar';`,
+ options: [
+ 'single',
+ {
+ avoidEscape: true,
+ },
+ ],
+ errors: [useSingleQuote],
+ },
+ {
+ code: `var foo = 'bar';`,
+ output: `var foo = "bar";`,
+ options: [
+ 'double',
+ {
+ avoidEscape: true,
+ },
+ ],
+ errors: [useDoubleQuote],
+ },
+ {
+ code: `var foo = '\\\\';`,
+ output: `var foo = "\\\\\";`, // eslint-disable-line no-useless-escape
+ options: [
+ 'double',
+ {
+ avoidEscape: true,
+ },
+ ],
+ errors: [useDoubleQuote],
+ },
+ {
+ code: `var foo = "bar";`,
+ output: `var foo = 'bar';`,
+ options: [
+ 'single',
+ {
+ allowTemplateLiterals: true,
+ },
+ ],
+ errors: [useSingleQuote],
+ },
+ {
+ code: `var foo = 'bar';`,
+ output: `var foo = "bar";`,
+ options: [
+ 'double',
+ {
+ allowTemplateLiterals: true,
+ },
+ ],
+ errors: [useDoubleQuote],
+ },
+ {
+ code: `var foo = 'bar';`,
+ output: 'var foo = `bar`;',
+ options: ['backtick'],
+ parserOptions: { ecmaVersion: 2015 },
+ errors: [useBacktick],
+ },
+ {
+ code: "var foo = 'b${x}a$r';",
+ output: 'var foo = `b\\${x}a$r`;',
+ options: ['backtick'],
+ parserOptions: { ecmaVersion: 2015 },
+ errors: [useBacktick],
+ },
+ {
+ code: 'var foo = "bar";',
+ output: 'var foo = `bar`;',
+ options: ['backtick'],
+ parserOptions: { ecmaVersion: 2015 },
+ errors: [useBacktick],
+ },
+ {
+ code: `var foo = "bar";`,
+ output: 'var foo = `bar`;',
+ options: [
+ 'backtick',
+ {
+ avoidEscape: true,
+ },
+ ],
+ parserOptions: { ecmaVersion: 2015 },
+ errors: [useBacktick],
+ },
+ {
+ code: `var foo = 'bar';`,
+ output: 'var foo = `bar`;',
+ options: [
+ 'backtick',
+ {
+ avoidEscape: true,
+ },
+ ],
+ parserOptions: { ecmaVersion: 2015 },
+ errors: [useBacktick],
+ },
+
+ // "use strict" is *not* a directive prologue in these statements so is subject to the rule
+ {
+ code: 'var foo = `backtick`; "use strict";',
+ output: 'var foo = `backtick`; `use strict`;',
+ options: ['backtick'],
+ parserOptions: { ecmaVersion: 6 },
+ errors: [useBacktick],
+ },
+ {
+ code: '{ "use strict"; var foo = `backtick`; }',
+ output: '{ `use strict`; var foo = `backtick`; }',
+ options: ['backtick'],
+ parserOptions: { ecmaVersion: 6 },
+ errors: [useBacktick],
+ },
+ {
+ code: 'if (1) { "use strict"; var foo = `backtick`; }',
+ output: 'if (1) { `use strict`; var foo = `backtick`; }',
+ options: ['backtick'],
+ parserOptions: { ecmaVersion: 6 },
+ errors: [useBacktick],
+ },
+
+ // `backtick` should warn computed property names.
+ {
+ code: `var obj = {["key0"]: 0, ['key1']: 1};`,
+ output: 'var obj = {[`key0`]: 0, [`key1`]: 1};',
+ options: ['backtick'],
+ parserOptions: { ecmaVersion: 6 },
+ errors: [useBacktick, useBacktick],
+ },
+ {
+ code: `class Foo { ['a'](){} static ['b'](){} }`,
+ output: 'class Foo { [`a`](){} static [`b`](){} }',
+ options: ['backtick'],
+ parserOptions: { ecmaVersion: 6 },
+ errors: [useBacktick, useBacktick],
+ },
+
+ // https://github.com/eslint/eslint/issues/7084
+ {
+ code: ``,
+ output: ``,
+ options: [`single`],
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true,
+ },
+ },
+ errors: [useSingleQuote],
+ },
+ {
+ code: ``,
+ output: ``,
+ options: ['double'],
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true,
+ },
+ },
+ errors: [useDoubleQuote],
+ },
+ {
+ code: ``,
+ output: '',
+ options: ['backtick'],
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true,
+ },
+ ecmaVersion: 2015,
+ },
+ errors: [useBacktick],
+ },
+
+ // https://github.com/eslint/eslint/issues/7610
+ {
+ code: '`use strict`;',
+ output: null,
+ parserOptions: { ecmaVersion: 6 },
+ errors: [useDoubleQuote],
+ },
+ {
+ code: 'function foo() { `use strict`; foo(); }',
+ output: null,
+ parserOptions: { ecmaVersion: 6 },
+ errors: [useDoubleQuote],
+ },
+ {
+ code: 'foo = function() { `use strict`; foo(); }',
+ output: null,
+ parserOptions: { ecmaVersion: 6 },
+ errors: [useDoubleQuote],
+ },
+ {
+ code: '() => { `use strict`; foo(); }',
+ output: null,
+ parserOptions: { ecmaVersion: 6 },
+ errors: [useDoubleQuote],
+ },
+ {
+ code: '() => { foo(); `use strict`; }',
+ output: `() => { foo(); "use strict"; }`,
+ parserOptions: { ecmaVersion: 6 },
+ errors: [useDoubleQuote],
+ },
+ {
+ code: 'foo(); `use strict`;',
+ output: 'foo(); "use strict";',
+ parserOptions: { ecmaVersion: 6 },
+ errors: [useDoubleQuote],
+ },
+
+ // https://github.com/eslint/eslint/issues/7646
+ {
+ code: 'var foo = `foo\\nbar`;',
+ output: 'var foo = "foo\\nbar";',
+ parserOptions: { ecmaVersion: 6 },
+ errors: [useDoubleQuote],
+ },
+ {
+ code: 'var foo = `foo\\\nbar`;', // 1 backslash followed by a newline
+ output: 'var foo = "foo\\\nbar";',
+ parserOptions: { ecmaVersion: 6 },
+ errors: [useDoubleQuote],
+ },
+ {
+ code: 'var foo = `foo\\\\\\\nbar`;', // 3 backslashes followed by a newline
+ output: 'var foo = "foo\\\\\\\nbar";',
+ parserOptions: { ecmaVersion: 6 },
+ errors: [useDoubleQuote],
+ },
+ {
+ code: '````',
+ output: '""``',
+ parserOptions: { ecmaVersion: 6 },
+ errors: [{ ...useDoubleQuote, line: 1, column: 1 }],
+ },
+ ],
+});
diff --git a/packages/eslint-plugin/tools/generate-configs.ts b/packages/eslint-plugin/tools/generate-configs.ts
index cda1b0771ea..b400ca05722 100644
--- a/packages/eslint-plugin/tools/generate-configs.ts
+++ b/packages/eslint-plugin/tools/generate-configs.ts
@@ -29,6 +29,7 @@ const BASE_RULES_TO_BE_OVERRIDDEN = new Set([
'no-empty-function',
'no-extra-parens',
'no-magic-numbers',
+ 'quotes',
'no-unused-vars',
'no-use-before-define',
'no-useless-constructor',
diff --git a/packages/eslint-plugin/typings/eslint-rules.d.ts b/packages/eslint-plugin/typings/eslint-rules.d.ts
index 4e5fe5b6449..dcc37035c9d 100644
--- a/packages/eslint-plugin/typings/eslint-rules.d.ts
+++ b/packages/eslint-plugin/typings/eslint-rules.d.ts
@@ -461,3 +461,23 @@ declare module 'eslint/lib/rules/semi' {
>;
export = rule;
}
+
+declare module 'eslint/lib/rules/quotes' {
+ import { TSESLint, TSESTree } from '@typescript-eslint/experimental-utils';
+
+ const rule: TSESLint.RuleModule<
+ never,
+ [
+ 'single' | 'double' | 'backtick',
+ {
+ allowTemplateLiterals?: boolean;
+ avoidEscape?: boolean;
+ }?,
+ ],
+ {
+ Literal(node: TSESTree.Literal): void;
+ TemplateLiteral(node: TSESTree.TemplateLiteral): void;
+ }
+ >;
+ export = rule;
+}