From 37dd87889c0bae02a624097b728f57e63f254fe8 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 21 Jan 2019 12:18:45 -0800 Subject: [PATCH 01/92] rename files and start migration --- packages/eslint-plugin/lib/util.js | 125 --------------- packages/eslint-plugin/package.json | 7 +- .../{lib/index.js => src/index.ts} | 6 +- .../{ => src}/lib/configs/recommended.json | 0 .../rules/adjacent-overload-signatures.ts} | 9 +- .../lib/rules/array-type.ts} | 6 +- .../lib/rules/ban-types.ts} | 6 +- .../lib/rules/camelcase.ts} | 8 +- .../lib/rules/class-name-casing.ts} | 6 +- .../rules/explicit-function-return-type.ts} | 6 +- .../rules/explicit-member-accessibility.ts} | 6 +- .../lib/rules/generic-type-naming.ts} | 6 +- .../indent.js => src/lib/rules/indent.ts} | 8 +- .../lib/rules/interface-name-prefix.ts} | 6 +- .../lib/rules/member-delimiter-style.ts} | 17 ++- .../lib/rules/member-naming.ts} | 6 +- .../lib/rules/member-ordering.ts} | 6 +- .../rules/no-angle-bracket-type-assertion.ts} | 6 +- .../lib/rules/no-array-constructor.ts} | 6 +- .../lib/rules/no-empty-interface.ts} | 6 +- .../lib/rules/no-explicit-any.ts} | 6 +- .../lib/rules/no-extraneous-class.ts} | 6 +- .../lib/rules/no-inferrable-types.ts} | 6 +- .../lib/rules/no-misused-new.ts} | 6 +- .../lib/rules/no-namespace.ts} | 6 +- .../lib/rules/no-non-null-assertion.ts} | 6 +- .../no-object-literal-type-assertion.ts} | 6 +- .../lib/rules/no-parameter-properties.ts} | 6 +- .../lib/rules/no-this-alias.ts} | 6 +- .../lib/rules/no-triple-slash-reference.ts} | 6 +- .../lib/rules/no-type-alias.ts} | 6 +- .../lib/rules/no-unused-vars.ts} | 8 +- .../lib/rules/no-use-before-define.ts} | 7 +- .../lib/rules/no-var-requires.ts} | 6 +- .../lib/rules/prefer-interface.ts} | 6 +- .../lib/rules/prefer-namespace-keyword.ts} | 6 +- .../lib/rules/type-annotation-spacing.ts} | 6 +- packages/eslint-plugin/src/lib/util.ts | 144 ++++++++++++++++++ packages/eslint-plugin/tsconfig.json | 8 + packages/typescript-estree/src/parser.ts | 49 +++--- tsconfig.json | 16 +- 41 files changed, 312 insertions(+), 262 deletions(-) delete mode 100644 packages/eslint-plugin/lib/util.js rename packages/eslint-plugin/{lib/index.js => src/index.ts} (87%) rename packages/eslint-plugin/{ => src}/lib/configs/recommended.json (100%) rename packages/eslint-plugin/{lib/rules/adjacent-overload-signatures.js => src/lib/rules/adjacent-overload-signatures.ts} (95%) rename packages/eslint-plugin/{lib/rules/array-type.js => src/lib/rules/array-type.ts} (98%) rename packages/eslint-plugin/{lib/rules/ban-types.js => src/lib/rules/ban-types.ts} (96%) rename packages/eslint-plugin/{lib/rules/camelcase.js => src/lib/rules/camelcase.ts} (95%) rename packages/eslint-plugin/{lib/rules/class-name-casing.js => src/lib/rules/class-name-casing.ts} (96%) rename packages/eslint-plugin/{lib/rules/explicit-function-return-type.js => src/lib/rules/explicit-function-return-type.ts} (96%) rename packages/eslint-plugin/{lib/rules/explicit-member-accessibility.js => src/lib/rules/explicit-member-accessibility.ts} (95%) rename packages/eslint-plugin/{lib/rules/generic-type-naming.js => src/lib/rules/generic-type-naming.ts} (91%) rename packages/eslint-plugin/{lib/rules/indent.js => src/lib/rules/indent.ts} (98%) rename packages/eslint-plugin/{lib/rules/interface-name-prefix.js => src/lib/rules/interface-name-prefix.ts} (95%) rename packages/eslint-plugin/{lib/rules/member-delimiter-style.js => src/lib/rules/member-delimiter-style.ts} (93%) rename packages/eslint-plugin/{lib/rules/member-naming.js => src/lib/rules/member-naming.ts} (95%) rename packages/eslint-plugin/{lib/rules/member-ordering.js => src/lib/rules/member-ordering.ts} (99%) rename packages/eslint-plugin/{lib/rules/no-angle-bracket-type-assertion.js => src/lib/rules/no-angle-bracket-type-assertion.ts} (92%) rename packages/eslint-plugin/{lib/rules/no-array-constructor.js => src/lib/rules/no-array-constructor.ts} (94%) rename packages/eslint-plugin/{lib/rules/no-empty-interface.js => src/lib/rules/no-empty-interface.ts} (93%) rename packages/eslint-plugin/{lib/rules/no-explicit-any.js => src/lib/rules/no-explicit-any.ts} (88%) rename packages/eslint-plugin/{lib/rules/no-extraneous-class.js => src/lib/rules/no-extraneous-class.ts} (96%) rename packages/eslint-plugin/{lib/rules/no-inferrable-types.js => src/lib/rules/no-inferrable-types.ts} (98%) rename packages/eslint-plugin/{lib/rules/no-misused-new.js => src/lib/rules/no-misused-new.ts} (96%) rename packages/eslint-plugin/{lib/rules/no-namespace.js => src/lib/rules/no-namespace.ts} (95%) rename packages/eslint-plugin/{lib/rules/no-non-null-assertion.js => src/lib/rules/no-non-null-assertion.ts} (90%) rename packages/eslint-plugin/{lib/rules/no-object-literal-type-assertion.js => src/lib/rules/no-object-literal-type-assertion.ts} (94%) rename packages/eslint-plugin/{lib/rules/no-parameter-properties.js => src/lib/rules/no-parameter-properties.ts} (96%) rename packages/eslint-plugin/{lib/rules/no-this-alias.js => src/lib/rules/no-this-alias.ts} (94%) rename packages/eslint-plugin/{lib/rules/no-triple-slash-reference.js => src/lib/rules/no-triple-slash-reference.ts} (94%) rename packages/eslint-plugin/{lib/rules/no-type-alias.js => src/lib/rules/no-type-alias.ts} (98%) rename packages/eslint-plugin/{lib/rules/no-unused-vars.js => src/lib/rules/no-unused-vars.ts} (94%) rename packages/eslint-plugin/{lib/rules/no-use-before-define.js => src/lib/rules/no-use-before-define.ts} (98%) rename packages/eslint-plugin/{lib/rules/no-var-requires.js => src/lib/rules/no-var-requires.ts} (91%) rename packages/eslint-plugin/{lib/rules/prefer-interface.js => src/lib/rules/prefer-interface.ts} (95%) rename packages/eslint-plugin/{lib/rules/prefer-namespace-keyword.js => src/lib/rules/prefer-namespace-keyword.ts} (94%) rename packages/eslint-plugin/{lib/rules/type-annotation-spacing.js => src/lib/rules/type-annotation-spacing.ts} (98%) create mode 100644 packages/eslint-plugin/src/lib/util.ts create mode 100644 packages/eslint-plugin/tsconfig.json diff --git a/packages/eslint-plugin/lib/util.js b/packages/eslint-plugin/lib/util.js deleted file mode 100644 index 1df02bfb9e8e..000000000000 --- a/packages/eslint-plugin/lib/util.js +++ /dev/null @@ -1,125 +0,0 @@ -'use strict'; - -const version = require('../package.json').version; - -exports.tslintRule = name => `\`${name}\` from TSLint`; - -exports.metaDocsUrl = name => - `https://github.com/typescript-eslint/typescript-eslint/blob/${version}/packages/eslint-plugin/docs/rules/${name}.md`; - -/** - * Check if the context file name is *.ts or *.tsx - * @param {string} fileName The context file name - * @returns {boolean} `true` if the file name ends in *.ts or *.tsx - * @private - */ -exports.isTypescript = fileName => /\.tsx?$/i.test(fileName || ''); - -/** - * Check if the context file name is *.d.ts or *.d.ts - * @param {string} fileName The context file name - * @returns {boolean} `true` if the file name ends in *.d.ts or *.d.ts - * @private - */ -exports.isDefinitionFile = fileName => /\.d\.tsx?$/i.test(fileName || ''); - -/** - * Check if the variable contains an object stricly rejecting arrays - * @param {any} obj an object - * @returns {boolean} `true` if obj is an object - */ -function isObjectNotArray(obj) { - return typeof obj === 'object' && !Array.isArray(obj); -} - -/** - * Pure function - doesn't mutate either parameter! - * Merges two objects together deeply, overwriting the properties in first with the properties in second - * @template TFirst,TSecond - * @param {TFirst} first The first object - * @param {TSecond} second The second object - * @returns {Record} a new object - */ -function deepMerge(first = {}, second = {}) { - // get the unique set of keys across both objects - const keys = new Set(Object.keys(first).concat(Object.keys(second))); - - return Array.from(keys).reduce((acc, key) => { - const firstHasKey = key in first; - const secondHasKey = key in second; - - if (firstHasKey && secondHasKey) { - if (isObjectNotArray(first[key]) && isObjectNotArray(second[key])) { - // object type - acc[key] = deepMerge(first[key], second[key]); - } else { - // value type - acc[key] = second[key]; - } - } else if (firstHasKey) { - acc[key] = first[key]; - } else { - acc[key] = second[key]; - } - - return acc; - }, {}); -} -exports.deepMerge = deepMerge; - -/** - * Pure function - doesn't mutate either parameter! - * Uses the default options and overrides with the options provided by the user - * @template TOptions - * @param {TOptions} defaultOptions the defaults - * @param {any[]} userOptions the user opts - * @returns {TOptions} the options with defaults - */ -exports.applyDefault = (defaultOptions, userOptions) => { - // clone defaults - const options = JSON.parse(JSON.stringify(defaultOptions)); - - // eslint-disable-next-line eqeqeq - if (userOptions == null) { - return options; - } - - options.forEach((opt, i) => { - if (userOptions[i]) { - const userOpt = userOptions[i]; - - if (isObjectNotArray(userOpt) && isObjectNotArray(opt)) { - options[i] = deepMerge(opt, userOpt); - } else { - options[i] = userOpt; - } - } - }); - - return options; -}; - -/** - * Upper cases the first character or the string - * @param {string} str a string - * @returns {string} upper case first - */ -exports.upperCaseFirst = str => str[0].toUpperCase() + str.slice(1); - -/** - * Try to retrieve typescript parser service from context - * @param {RuleContext} context Rule context - * @returns {{esTreeNodeToTSNodeMap}|{program}|Object|*} parserServices - */ -exports.getParserServices = context => { - if ( - !context.parserServices || - !context.parserServices.program || - !context.parserServices.esTreeNodeToTSNodeMap - ) { - throw new Error( - 'This rule requires you to use `@typescript-eslint/parser`.' - ); - } - return context.parserServices; -}; diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 34d125380e4c..990d1feee1e2 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -16,12 +16,15 @@ "url": "https://github.com/typescript-eslint/typescript-eslint/issues" }, "license": "MIT", - "main": "lib/index.js", + "main": "dist/index.js", "scripts": { "docs": "eslint-docs", "docs:check": "eslint-docs check", "test": "jest --coverage", - "recommended:update": "node tools/update-recommended.js" + "recommended:update": "node tools/update-recommended.js", + "prebuild": "npm run clean", + "build": "tsc", + "clean": "rimraf dist/" }, "dependencies": { "@typescript-eslint/parser": "1.0.0", diff --git a/packages/eslint-plugin/lib/index.js b/packages/eslint-plugin/src/index.ts similarity index 87% rename from packages/eslint-plugin/lib/index.js rename to packages/eslint-plugin/src/index.ts index 1dcee891d941..fd00335d7251 100644 --- a/packages/eslint-plugin/lib/index.js +++ b/packages/eslint-plugin/src/index.ts @@ -8,15 +8,15 @@ // Requirements //------------------------------------------------------------------------------ -const requireIndex = require('requireindex'); -const path = require('path'); +import requireIndex from 'requireindex'; +import path from 'path'; //------------------------------------------------------------------------------ // Plugin Definition //------------------------------------------------------------------------------ // import all rules in lib/rules -module.exports = { +export default { rules: requireIndex(path.join(__dirname, 'rules')), configs: { // eslint-disable-next-line node/no-unpublished-require diff --git a/packages/eslint-plugin/lib/configs/recommended.json b/packages/eslint-plugin/src/lib/configs/recommended.json similarity index 100% rename from packages/eslint-plugin/lib/configs/recommended.json rename to packages/eslint-plugin/src/lib/configs/recommended.json diff --git a/packages/eslint-plugin/lib/rules/adjacent-overload-signatures.js b/packages/eslint-plugin/src/lib/rules/adjacent-overload-signatures.ts similarity index 95% rename from packages/eslint-plugin/lib/rules/adjacent-overload-signatures.js rename to packages/eslint-plugin/src/lib/rules/adjacent-overload-signatures.ts index d8eb79509558..0089fa1cc106 100644 --- a/packages/eslint-plugin/lib/rules/adjacent-overload-signatures.js +++ b/packages/eslint-plugin/src/lib/rules/adjacent-overload-signatures.ts @@ -2,9 +2,10 @@ * @fileoverview Enforces member overloads to be consecutive. * @author Patricio Trevino */ -'use strict'; -const util = require('../util'); +import { Node } from 'estree'; +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -26,7 +27,7 @@ module.exports = { } }, - create(context) { + create(context: Rule.RuleContext) { //---------------------------------------------------------------------- // Helpers //---------------------------------------------------------------------- @@ -37,7 +38,7 @@ module.exports = { * @returns {string|null} the name of the member or null if it's a member not relevant to the rule. * @private */ - function getMemberName(member) { + function getMemberName(member: Node) { if (!member) return null; switch (member.type) { diff --git a/packages/eslint-plugin/lib/rules/array-type.js b/packages/eslint-plugin/src/lib/rules/array-type.ts similarity index 98% rename from packages/eslint-plugin/lib/rules/array-type.js rename to packages/eslint-plugin/src/lib/rules/array-type.ts index 9d30f23cfb4f..973ac2944960 100644 --- a/packages/eslint-plugin/lib/rules/array-type.js +++ b/packages/eslint-plugin/src/lib/rules/array-type.ts @@ -3,9 +3,9 @@ * @author Mackie Underdown * @author Armano */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; /** * Check whatever node can be considered as simple @@ -106,7 +106,7 @@ module.exports = { } ] }, - create(context) { + create(context: Rule.RuleContext) { const option = util.applyDefault(defaultOptions, context.options)[0]; const sourceCode = context.getSourceCode(); diff --git a/packages/eslint-plugin/lib/rules/ban-types.js b/packages/eslint-plugin/src/lib/rules/ban-types.ts similarity index 96% rename from packages/eslint-plugin/lib/rules/ban-types.js rename to packages/eslint-plugin/src/lib/rules/ban-types.ts index 42dd693463ab..abba5dd2766c 100644 --- a/packages/eslint-plugin/lib/rules/ban-types.js +++ b/packages/eslint-plugin/src/lib/rules/ban-types.ts @@ -2,9 +2,9 @@ * @fileoverview Enforces that types will not to be used * @author Armano */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -78,7 +78,7 @@ module.exports = { ] }, - create(context) { + create(context: Rule.RuleContext) { const banedTypes = util.applyDefault(defaultOptions, context.options)[0] .types; diff --git a/packages/eslint-plugin/lib/rules/camelcase.js b/packages/eslint-plugin/src/lib/rules/camelcase.ts similarity index 95% rename from packages/eslint-plugin/lib/rules/camelcase.js rename to packages/eslint-plugin/src/lib/rules/camelcase.ts index cffc47366cc9..6f713b52517e 100644 --- a/packages/eslint-plugin/lib/rules/camelcase.js +++ b/packages/eslint-plugin/src/lib/rules/camelcase.ts @@ -2,10 +2,10 @@ * @fileoverview Rule to flag non-camelcased identifiers * @author Patricio Trevino */ -'use strict'; -const baseRule = require('eslint/lib/rules/camelcase'); -const util = require('../util'); +import { Rule } from 'eslint'; +import baseRule from 'eslint/lib/rules/camelcase'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -28,7 +28,7 @@ module.exports = { } }), - create(context) { + create(context: Rule.RuleContext) { const rules = baseRule.create(context); const TS_PROPERTY_TYPES = [ 'TSPropertySignature', diff --git a/packages/eslint-plugin/lib/rules/class-name-casing.js b/packages/eslint-plugin/src/lib/rules/class-name-casing.ts similarity index 96% rename from packages/eslint-plugin/lib/rules/class-name-casing.js rename to packages/eslint-plugin/src/lib/rules/class-name-casing.ts index 3b8db844efab..18ab9263e563 100644 --- a/packages/eslint-plugin/lib/rules/class-name-casing.js +++ b/packages/eslint-plugin/src/lib/rules/class-name-casing.ts @@ -3,9 +3,9 @@ * @author Jed Fox * @author Armano */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -24,7 +24,7 @@ module.exports = { schema: [] }, - create(context) { + create(context: Rule.RuleContext) { // variables should be defined here //---------------------------------------------------------------------- diff --git a/packages/eslint-plugin/lib/rules/explicit-function-return-type.js b/packages/eslint-plugin/src/lib/rules/explicit-function-return-type.ts similarity index 96% rename from packages/eslint-plugin/lib/rules/explicit-function-return-type.js rename to packages/eslint-plugin/src/lib/rules/explicit-function-return-type.ts index 0253d80d3c99..4e383421cfd7 100644 --- a/packages/eslint-plugin/lib/rules/explicit-function-return-type.js +++ b/packages/eslint-plugin/src/lib/rules/explicit-function-return-type.ts @@ -2,9 +2,9 @@ * @fileoverview Enforces explicit return type for functions * @author Scott O'Hara */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -39,7 +39,7 @@ module.exports = { ] }, - create(context) { + create(context: Rule.RuleContext) { const options = util.applyDefault(defaultOptions, context.options)[0]; //---------------------------------------------------------------------- diff --git a/packages/eslint-plugin/lib/rules/explicit-member-accessibility.js b/packages/eslint-plugin/src/lib/rules/explicit-member-accessibility.ts similarity index 95% rename from packages/eslint-plugin/lib/rules/explicit-member-accessibility.js rename to packages/eslint-plugin/src/lib/rules/explicit-member-accessibility.ts index e3f041ea2ff1..616a18259e48 100644 --- a/packages/eslint-plugin/lib/rules/explicit-member-accessibility.js +++ b/packages/eslint-plugin/src/lib/rules/explicit-member-accessibility.ts @@ -2,9 +2,9 @@ * @fileoverview Enforces explicit accessibility modifier for class members * @author Danny Fritz */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -24,7 +24,7 @@ module.exports = { schema: [] }, - create(context) { + create(context: Rule.RuleContext) { //---------------------------------------------------------------------- // Helpers //---------------------------------------------------------------------- diff --git a/packages/eslint-plugin/lib/rules/generic-type-naming.js b/packages/eslint-plugin/src/lib/rules/generic-type-naming.ts similarity index 91% rename from packages/eslint-plugin/lib/rules/generic-type-naming.js rename to packages/eslint-plugin/src/lib/rules/generic-type-naming.ts index f14c8f50e891..72897bde345d 100644 --- a/packages/eslint-plugin/lib/rules/generic-type-naming.js +++ b/packages/eslint-plugin/src/lib/rules/generic-type-naming.ts @@ -1,9 +1,9 @@ /** * @fileoverview Enforces naming of generic type variables. */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; const defaultOptions = [ // Matches: T , TA , TAbc , TA1Bca , T1 , T2 @@ -29,7 +29,7 @@ module.exports = { recommended: 'error' }, - create(context) { + create(context: Rule.RuleContext) { const rule = util.applyDefault(defaultOptions, context.options)[0]; const regex = new RegExp(rule); diff --git a/packages/eslint-plugin/lib/rules/indent.js b/packages/eslint-plugin/src/lib/rules/indent.ts similarity index 98% rename from packages/eslint-plugin/lib/rules/indent.js rename to packages/eslint-plugin/src/lib/rules/indent.ts index 84144219faff..3b08b3606831 100644 --- a/packages/eslint-plugin/lib/rules/indent.js +++ b/packages/eslint-plugin/src/lib/rules/indent.ts @@ -2,10 +2,10 @@ * @fileoverview Rule to flag non-camelcased identifiers * @author Patricio Trevino */ -'use strict'; -const baseRule = require('eslint/lib/rules/indent'); -const util = require('../util'); +import { Rule } from 'eslint'; +import baseRule from 'eslint/lib/rules/indent'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -105,7 +105,7 @@ module.exports = Object.assign({}, baseRule, { messages: baseRule.meta.messages }, - create(context) { + create(context: Rule.RuleContext) { // because we extend the base rule, have to update opts on the context // the context defines options as readonly though... const contextWithDefaults = Object.create(context, { diff --git a/packages/eslint-plugin/lib/rules/interface-name-prefix.js b/packages/eslint-plugin/src/lib/rules/interface-name-prefix.ts similarity index 95% rename from packages/eslint-plugin/lib/rules/interface-name-prefix.js rename to packages/eslint-plugin/src/lib/rules/interface-name-prefix.ts index fc5d0da82293..fc695a653481 100644 --- a/packages/eslint-plugin/lib/rules/interface-name-prefix.js +++ b/packages/eslint-plugin/src/lib/rules/interface-name-prefix.ts @@ -2,9 +2,9 @@ * @fileoverview Enforces interface names are prefixed with "I". * @author Danny Fritz */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -29,7 +29,7 @@ module.exports = { ] }, - create(context) { + create(context: Rule.RuleContext) { const option = util.applyDefault(defaultOptions, context.options)[0]; const never = option !== 'always'; diff --git a/packages/eslint-plugin/lib/rules/member-delimiter-style.js b/packages/eslint-plugin/src/lib/rules/member-delimiter-style.ts similarity index 93% rename from packages/eslint-plugin/lib/rules/member-delimiter-style.js rename to packages/eslint-plugin/src/lib/rules/member-delimiter-style.ts index 2fc49166ba36..ef34066aaf42 100644 --- a/packages/eslint-plugin/lib/rules/member-delimiter-style.js +++ b/packages/eslint-plugin/src/lib/rules/member-delimiter-style.ts @@ -3,9 +3,9 @@ * @author Patricio Trevino * @author Brad Zacher */ -'use strict'; -const { deepMerge, metaDocsUrl, applyDefault } = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -55,7 +55,7 @@ module.exports = { description: 'Require a specific member delimiter style for interfaces and type literals', category: 'TypeScript', - url: metaDocsUrl('member-delimiter-style'), + url: util.metaDocsUrl('member-delimiter-style'), recommended: 'error' }, fixable: 'code', @@ -83,15 +83,18 @@ module.exports = { ] }, - create(context) { + create(context: Rule.RuleContext) { const sourceCode = context.getSourceCode(); - const options = applyDefault(defaultOptions, context.options)[0]; + const options = util.applyDefault(defaultOptions, context.options)[0]; // use the base options as the defaults for the cases const baseOptions = options; const overrides = baseOptions.overrides || {}; - const interfaceOptions = deepMerge(baseOptions, overrides.interface); - const typeLiteralOptions = deepMerge(baseOptions, overrides.typeLiteral); + const interfaceOptions = util.deepMerge(baseOptions, overrides.interface); + const typeLiteralOptions = util.deepMerge( + baseOptions, + overrides.typeLiteral + ); //---------------------------------------------------------------------- // Helpers diff --git a/packages/eslint-plugin/lib/rules/member-naming.js b/packages/eslint-plugin/src/lib/rules/member-naming.ts similarity index 95% rename from packages/eslint-plugin/lib/rules/member-naming.js rename to packages/eslint-plugin/src/lib/rules/member-naming.ts index 49dc33570c83..1b3660ee57c1 100644 --- a/packages/eslint-plugin/lib/rules/member-naming.js +++ b/packages/eslint-plugin/src/lib/rules/member-naming.ts @@ -2,9 +2,9 @@ * @fileoverview Enforces naming conventions for class members by visibility. * @author Ian MacLeod */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -48,7 +48,7 @@ module.exports = { ] }, - create(context) { + create(context: Rule.RuleContext) { const config = util.applyDefault(defaultOptions, context.options)[0]; const conventions = Object.keys(config).reduce((acc, accessibility) => { acc[accessibility] = new RegExp(config[accessibility]); diff --git a/packages/eslint-plugin/lib/rules/member-ordering.js b/packages/eslint-plugin/src/lib/rules/member-ordering.ts similarity index 99% rename from packages/eslint-plugin/lib/rules/member-ordering.js rename to packages/eslint-plugin/src/lib/rules/member-ordering.ts index e8b72ac0bcc2..6d1e6f8e85ad 100644 --- a/packages/eslint-plugin/lib/rules/member-ordering.js +++ b/packages/eslint-plugin/src/lib/rules/member-ordering.ts @@ -2,9 +2,9 @@ * @fileoverview Enforces a standard member declaration order. * @author Patricio Trevino */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -158,7 +158,7 @@ module.exports = { ] }, - create(context) { + create(context: Rule.RuleContext) { const options = util.applyDefault(defaultOptions, context.options)[0]; const functionExpressions = [ diff --git a/packages/eslint-plugin/lib/rules/no-angle-bracket-type-assertion.js b/packages/eslint-plugin/src/lib/rules/no-angle-bracket-type-assertion.ts similarity index 92% rename from packages/eslint-plugin/lib/rules/no-angle-bracket-type-assertion.js rename to packages/eslint-plugin/src/lib/rules/no-angle-bracket-type-assertion.ts index f030079c235f..2f44527ef3a8 100644 --- a/packages/eslint-plugin/lib/rules/no-angle-bracket-type-assertion.js +++ b/packages/eslint-plugin/src/lib/rules/no-angle-bracket-type-assertion.ts @@ -2,9 +2,9 @@ * @fileoverview Enforces the use of `as Type` assertions instead of `` assertions. * @author Patricio Trevino */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -24,7 +24,7 @@ module.exports = { schema: [] }, - create(context) { + create(context: Rule.RuleContext) { const sourceCode = context.getSourceCode(); //---------------------------------------------------------------------- diff --git a/packages/eslint-plugin/lib/rules/no-array-constructor.js b/packages/eslint-plugin/src/lib/rules/no-array-constructor.ts similarity index 94% rename from packages/eslint-plugin/lib/rules/no-array-constructor.js rename to packages/eslint-plugin/src/lib/rules/no-array-constructor.ts index bf4139396c2e..5bc068164cf2 100644 --- a/packages/eslint-plugin/lib/rules/no-array-constructor.js +++ b/packages/eslint-plugin/src/lib/rules/no-array-constructor.ts @@ -3,9 +3,9 @@ * @author Jed Fox * @author Matt DuVall */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -24,7 +24,7 @@ module.exports = { schema: [] }, - create(context) { + create(context: Rule.RuleContext) { /** * Disallow construction of dense arrays using the Array constructor * @param {ASTNode} node node to evaluate diff --git a/packages/eslint-plugin/lib/rules/no-empty-interface.js b/packages/eslint-plugin/src/lib/rules/no-empty-interface.ts similarity index 93% rename from packages/eslint-plugin/lib/rules/no-empty-interface.js rename to packages/eslint-plugin/src/lib/rules/no-empty-interface.ts index 8caf42a9f626..41c79605d315 100644 --- a/packages/eslint-plugin/lib/rules/no-empty-interface.js +++ b/packages/eslint-plugin/src/lib/rules/no-empty-interface.ts @@ -2,9 +2,9 @@ * @fileoverview Disallows the declaration of empty interfaces. * @author Patricio Trevino */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -27,7 +27,7 @@ module.exports = { // Public //---------------------------------------------------------------------- - create(context) { + create(context: Rule.RuleContext) { return { TSInterfaceDeclaration(node) { if (node.body.body.length !== 0) { diff --git a/packages/eslint-plugin/lib/rules/no-explicit-any.js b/packages/eslint-plugin/src/lib/rules/no-explicit-any.ts similarity index 88% rename from packages/eslint-plugin/lib/rules/no-explicit-any.js rename to packages/eslint-plugin/src/lib/rules/no-explicit-any.ts index b8b77fe063b0..c0b4e7f7097a 100644 --- a/packages/eslint-plugin/lib/rules/no-explicit-any.js +++ b/packages/eslint-plugin/src/lib/rules/no-explicit-any.ts @@ -3,9 +3,9 @@ * @author Danny Fritz * @author Patricio Trevino */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -24,7 +24,7 @@ module.exports = { schema: [] }, - create(context) { + create(context: Rule.RuleContext) { return { TSAnyKeyword(node) { context.report({ diff --git a/packages/eslint-plugin/lib/rules/no-extraneous-class.js b/packages/eslint-plugin/src/lib/rules/no-extraneous-class.ts similarity index 96% rename from packages/eslint-plugin/lib/rules/no-extraneous-class.js rename to packages/eslint-plugin/src/lib/rules/no-extraneous-class.ts index e2eb3f0216dc..52dbcaff3953 100644 --- a/packages/eslint-plugin/lib/rules/no-extraneous-class.js +++ b/packages/eslint-plugin/src/lib/rules/no-extraneous-class.ts @@ -2,9 +2,9 @@ * @fileoverview Forbids the use of classes as namespaces * @author Jed Fox */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -53,7 +53,7 @@ module.exports = { } }, - create(context) { + create(context: Rule.RuleContext) { const { allowConstructorOnly, allowEmpty, diff --git a/packages/eslint-plugin/lib/rules/no-inferrable-types.js b/packages/eslint-plugin/src/lib/rules/no-inferrable-types.ts similarity index 98% rename from packages/eslint-plugin/lib/rules/no-inferrable-types.js rename to packages/eslint-plugin/src/lib/rules/no-inferrable-types.ts index a6318bf9bb5d..4902375539f1 100644 --- a/packages/eslint-plugin/lib/rules/no-inferrable-types.js +++ b/packages/eslint-plugin/src/lib/rules/no-inferrable-types.ts @@ -2,9 +2,9 @@ * @fileoverview Disallows explicit type declarations for inferrable types * @author James Garbutt */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -45,7 +45,7 @@ module.exports = { ] }, - create(context) { + create(context: Rule.RuleContext) { const { ignoreParameters, ignoreProperties } = util.applyDefault( defaultOptions, context.options diff --git a/packages/eslint-plugin/lib/rules/no-misused-new.js b/packages/eslint-plugin/src/lib/rules/no-misused-new.ts similarity index 96% rename from packages/eslint-plugin/lib/rules/no-misused-new.js rename to packages/eslint-plugin/src/lib/rules/no-misused-new.ts index bb4132289c5e..8d0242b2d4ca 100644 --- a/packages/eslint-plugin/lib/rules/no-misused-new.js +++ b/packages/eslint-plugin/src/lib/rules/no-misused-new.ts @@ -2,9 +2,9 @@ * @fileoverview Enforce valid definition of `new` and `constructor`. * @author Armano */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -31,7 +31,7 @@ module.exports = { // Public //---------------------------------------------------------------------- - create(context) { + create(context: Rule.RuleContext) { /** * @param {ASTNode} node type to be inspected. * @returns {string|null} name of simple type or null diff --git a/packages/eslint-plugin/lib/rules/no-namespace.js b/packages/eslint-plugin/src/lib/rules/no-namespace.ts similarity index 95% rename from packages/eslint-plugin/lib/rules/no-namespace.js rename to packages/eslint-plugin/src/lib/rules/no-namespace.ts index fe4ca8bebb8b..117f9ff58159 100644 --- a/packages/eslint-plugin/lib/rules/no-namespace.js +++ b/packages/eslint-plugin/src/lib/rules/no-namespace.ts @@ -2,9 +2,9 @@ * @fileoverview Disallows the use of custom TypeScript modules and namespaces. * @author Patricio Trevino */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -48,7 +48,7 @@ module.exports = { ] }, - create(context) { + create(context: Rule.RuleContext) { const { allowDeclarations, allowDefinitionFiles } = util.applyDefault( defaultOptions, context.options diff --git a/packages/eslint-plugin/lib/rules/no-non-null-assertion.js b/packages/eslint-plugin/src/lib/rules/no-non-null-assertion.ts similarity index 90% rename from packages/eslint-plugin/lib/rules/no-non-null-assertion.js rename to packages/eslint-plugin/src/lib/rules/no-non-null-assertion.ts index e67b6b7675b2..4fc2a86f3e87 100644 --- a/packages/eslint-plugin/lib/rules/no-non-null-assertion.js +++ b/packages/eslint-plugin/src/lib/rules/no-non-null-assertion.ts @@ -2,9 +2,9 @@ * @fileoverview Disallows non-null assertions using the `!` postfix operator. * @author Macklin Underdown */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -23,7 +23,7 @@ module.exports = { }, schema: [] }, - create(context) { + create(context: Rule.RuleContext) { //---------------------------------------------------------------------- // Public //---------------------------------------------------------------------- diff --git a/packages/eslint-plugin/lib/rules/no-object-literal-type-assertion.js b/packages/eslint-plugin/src/lib/rules/no-object-literal-type-assertion.ts similarity index 94% rename from packages/eslint-plugin/lib/rules/no-object-literal-type-assertion.js rename to packages/eslint-plugin/src/lib/rules/no-object-literal-type-assertion.ts index f98a28a38f0c..8d644ba9b9a8 100644 --- a/packages/eslint-plugin/lib/rules/no-object-literal-type-assertion.js +++ b/packages/eslint-plugin/src/lib/rules/no-object-literal-type-assertion.ts @@ -2,9 +2,9 @@ * @fileoverview Forbids an object literal to appear in a type assertion expression * @author Armano */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -27,7 +27,7 @@ module.exports = { }, schema: [] }, - create(context) { + create(context: Rule.RuleContext) { //---------------------------------------------------------------------- // Public //---------------------------------------------------------------------- diff --git a/packages/eslint-plugin/lib/rules/no-parameter-properties.js b/packages/eslint-plugin/src/lib/rules/no-parameter-properties.ts similarity index 96% rename from packages/eslint-plugin/lib/rules/no-parameter-properties.js rename to packages/eslint-plugin/src/lib/rules/no-parameter-properties.ts index d41066a8aa61..90e5721d5e1e 100644 --- a/packages/eslint-plugin/lib/rules/no-parameter-properties.js +++ b/packages/eslint-plugin/src/lib/rules/no-parameter-properties.ts @@ -2,9 +2,9 @@ * @fileoverview Disallows parameter properties in class constructors. * @author Patricio Trevino */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -52,7 +52,7 @@ module.exports = { ] }, - create(context) { + create(context: Rule.RuleContext) { const { allows } = util.applyDefault(defaultOptions, context.options)[0]; //---------------------------------------------------------------------- diff --git a/packages/eslint-plugin/lib/rules/no-this-alias.js b/packages/eslint-plugin/src/lib/rules/no-this-alias.ts similarity index 94% rename from packages/eslint-plugin/lib/rules/no-this-alias.js rename to packages/eslint-plugin/src/lib/rules/no-this-alias.ts index fd247ebe654c..c4aa6e7b0038 100644 --- a/packages/eslint-plugin/lib/rules/no-this-alias.js +++ b/packages/eslint-plugin/src/lib/rules/no-this-alias.ts @@ -2,9 +2,9 @@ * @fileoverview Disallow aliasing `this` * @author Jed Fox */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -52,7 +52,7 @@ module.exports = { } }, - create(context) { + create(context: Rule.RuleContext) { const { allowDestructuring, allowedNames } = util.applyDefault( defaultOptions, context.options diff --git a/packages/eslint-plugin/lib/rules/no-triple-slash-reference.js b/packages/eslint-plugin/src/lib/rules/no-triple-slash-reference.ts similarity index 94% rename from packages/eslint-plugin/lib/rules/no-triple-slash-reference.js rename to packages/eslint-plugin/src/lib/rules/no-triple-slash-reference.ts index 900861590578..7678dfa1eed5 100644 --- a/packages/eslint-plugin/lib/rules/no-triple-slash-reference.js +++ b/packages/eslint-plugin/src/lib/rules/no-triple-slash-reference.ts @@ -2,9 +2,9 @@ * @fileoverview Enforces triple slash references are not used. * @author Danny Fritz */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -26,7 +26,7 @@ module.exports = { } }, - create(context) { + create(context: Rule.RuleContext) { const referenceRegExp = /^\/\s* */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -27,7 +27,7 @@ module.exports = { }, schema: [] }, - create(context) { + create(context: Rule.RuleContext) { const sourceCode = context.getSourceCode(); //---------------------------------------------------------------------- diff --git a/packages/eslint-plugin/lib/rules/prefer-namespace-keyword.js b/packages/eslint-plugin/src/lib/rules/prefer-namespace-keyword.ts similarity index 94% rename from packages/eslint-plugin/lib/rules/prefer-namespace-keyword.js rename to packages/eslint-plugin/src/lib/rules/prefer-namespace-keyword.ts index 941d4f230920..7eb5ef92f2c5 100644 --- a/packages/eslint-plugin/lib/rules/prefer-namespace-keyword.js +++ b/packages/eslint-plugin/src/lib/rules/prefer-namespace-keyword.ts @@ -3,9 +3,9 @@ * @author Patricio Trevino * @author Armano */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -26,7 +26,7 @@ module.exports = { schema: [] }, - create(context) { + create(context: Rule.RuleContext) { const sourceCode = context.getSourceCode(); //---------------------------------------------------------------------- diff --git a/packages/eslint-plugin/lib/rules/type-annotation-spacing.js b/packages/eslint-plugin/src/lib/rules/type-annotation-spacing.ts similarity index 98% rename from packages/eslint-plugin/lib/rules/type-annotation-spacing.js rename to packages/eslint-plugin/src/lib/rules/type-annotation-spacing.ts index e20c1b230ebe..724cc7849fd8 100644 --- a/packages/eslint-plugin/lib/rules/type-annotation-spacing.js +++ b/packages/eslint-plugin/src/lib/rules/type-annotation-spacing.ts @@ -3,9 +3,9 @@ * @author Nicholas C. Zakas * @author Patricio Trevino */ -'use strict'; -const util = require('../util'); +import { Rule } from 'eslint'; +import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition @@ -56,7 +56,7 @@ module.exports = { ] }, - create(context) { + create(context: Rule.RuleContext) { const punctuators = [':', '=>']; const sourceCode = context.getSourceCode(); const options = util.applyDefault(defaultOptions, context.options)[0]; diff --git a/packages/eslint-plugin/src/lib/util.ts b/packages/eslint-plugin/src/lib/util.ts new file mode 100644 index 000000000000..a0d5721ba8e8 --- /dev/null +++ b/packages/eslint-plugin/src/lib/util.ts @@ -0,0 +1,144 @@ +import { Rule } from 'eslint'; +import { ParserServices } from '@typescript-eslint/typescript-estree'; + +const version = require('../../package.json').version; + +export type ObjectLike = Record; + +export function tslintRule(name: string) { + return `\`${name}\` from TSLint`; +} + +export function metaDocsUrl(name: string) { + return `https://github.com/typescript-eslint/typescript-eslint/blob/${version}/packages/eslint-plugin/docs/rules/${name}.md`; +} + +/** + * Check if the context file name is *.ts or *.tsx + * @param fileName The context file name + * @returns `true` if the file name ends in *.ts or *.tsx + * @private + */ +export function isTypescript(fileName: string) { + return /\.tsx?$/i.test(fileName || ''); +} + +/** + * Check if the context file name is *.d.ts or *.d.ts + * @param fileName The context file name + * @returns `true` if the file name ends in *.d.ts or *.d.ts + * @private + */ +export function isDefinitionFile(fileName: string) { + return /\.d\.tsx?$/i.test(fileName || ''); +} + +/** + * Check if the variable contains an object stricly rejecting arrays + * @param obj an object + * @returns `true` if obj is an object + */ +function isObjectNotArray(obj: T | Array): obj is T { + return typeof obj === 'object' && !Array.isArray(obj); +} + +/** + * Pure function - doesn't mutate either parameter! + * Merges two objects together deeply, overwriting the properties in first with the properties in second + * @param first The first object + * @param second The second object + * @returns a new object + */ +export function deepMerge( + first: ObjectLike = {}, + second: ObjectLike = {} +): T { + // get the unique set of keys across both objects + const keys = new Set(Object.keys(first).concat(Object.keys(second))); + + return Array.from(keys).reduce( + (acc, key) => { + const firstHasKey = key in first; + const secondHasKey = key in second; + + if (firstHasKey && secondHasKey) { + if (isObjectNotArray(first[key]) && isObjectNotArray(second[key])) { + // object type + acc[key] = deepMerge(first[key], second[key]); + } else { + // value type + acc[key] = second[key]; + } + } else if (firstHasKey) { + acc[key] = first[key]; + } else { + acc[key] = second[key]; + } + + return acc; + }, + {} as T + ); +} + +/** + * Pure function - doesn't mutate either parameter! + * Uses the default options and overrides with the options provided by the user + * @template TOptions + * @param defaultOptions the defaults + * @param userOptions the user opts + * @returns the options with defaults + */ +export function applyDefault( + defaultOptions: T, + userOptions: T | null +): T { + // clone defaults + const options: T = JSON.parse(JSON.stringify(defaultOptions)); + + // eslint-disable-next-line eqeqeq + if (userOptions == null) { + return options; + } + + options.forEach((opt, i) => { + if (userOptions[i]) { + const userOpt = userOptions[i]; + + if (isObjectNotArray(userOpt) && isObjectNotArray(opt)) { + options[i] = deepMerge(opt, userOpt); + } else { + options[i] = userOpt; + } + } + }); + + return options; +} + +/** + * Upper cases the first character or the string + * @param str a string + * @returns upper case first + */ +export function upperCaseFirst(str: string) { + return str[0].toUpperCase() + str.slice(1); +} + +/** + * Try to retrieve typescript parser service from context + * @param {RuleContext} context Rule context + * @returns {{esTreeNodeToTSNodeMap}|{program}|Object|*} parserServices + */ +export function getParserServices(context: Rule.RuleContext): ParserServices { + if ( + !context.parserServices || + !context.parserServices.program || + !context.parserServices.esTreeNodeToTSNodeMap + ) { + throw new Error( + 'This rule requires you to use `@typescript-eslint/parser`.' + ); + } + return context.parserServices; +} diff --git a/packages/eslint-plugin/tsconfig.json b/packages/eslint-plugin/tsconfig.json new file mode 100644 index 000000000000..8b51ca27bda3 --- /dev/null +++ b/packages/eslint-plugin/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "declaration": true, + "outDir": "./dist" + }, + "include": ["src", "typings"] +} diff --git a/packages/typescript-estree/src/parser.ts b/packages/typescript-estree/src/parser.ts index 2f6347e0a7a2..cdf62ac7a472 100644 --- a/packages/typescript-estree/src/parser.ts +++ b/packages/typescript-estree/src/parser.ts @@ -189,10 +189,10 @@ type AST = Program & /** * Parses the given source code to produce a valid AST - * @param {string} code TypeScript code - * @param {boolean} shouldGenerateServices Flag determining whether to generate ast maps and program or not - * @param {ParserOptions} options configuration object for the parser - * @returns {Object} the AST + * @param code TypeScript code + * @param shouldGenerateServices Flag determining whether to generate ast maps and program or not + * @param options configuration object for the parser + * @returns the AST */ function generateAST( code: string, @@ -200,18 +200,11 @@ function generateAST( shouldGenerateServices = false ): { estree: AST; - program: typeof shouldGenerateServices extends true - ? ts.Program - : (ts.Program | undefined); - astMaps: typeof shouldGenerateServices extends true - ? { - esTreeNodeToTSNodeMap: WeakMap; - tsNodeToESTreeNodeMap: WeakMap; - } - : { - esTreeNodeToTSNodeMap?: WeakMap; - tsNodeToESTreeNodeMap?: WeakMap; - }; + program: ts.Program | undefined; + astMaps: { + esTreeNodeToTSNodeMap?: WeakMap; + tsNodeToESTreeNodeMap?: WeakMap; + }; } { const toString = String; @@ -342,7 +335,10 @@ function generateAST( program: shouldProvideParserServices ? program : undefined, astMaps: shouldProvideParserServices ? astMaps! - : { esTreeNodeToTSNodeMap: undefined, tsNodeToESTreeNodeMap: undefined } + : { + esTreeNodeToTSNodeMap: undefined, + tsNodeToESTreeNodeMap: undefined + } }; } @@ -364,14 +360,25 @@ export function parse( return generateAST(code, options).estree; } -export function parseAndGenerateServices(code: string, options: ParserOptions) { +export type ParserServices = { + program: ts.Program; + esTreeNodeToTSNodeMap: WeakMap; + tsNodeToESTreeNodeMap: WeakMap; +}; +export function parseAndGenerateServices( + code: string, + options: T +): { + ast: AST; + services: ParserServices; +} { const result = generateAST(code, options, /*shouldGenerateServices*/ true); return { ast: result.estree, services: { - program: result.program, - esTreeNodeToTSNodeMap: result.astMaps.esTreeNodeToTSNodeMap, - tsNodeToESTreeNodeMap: result.astMaps.tsNodeToESTreeNodeMap + program: result.program!, + esTreeNodeToTSNodeMap: result.astMaps.esTreeNodeToTSNodeMap!, + tsNodeToESTreeNodeMap: result.astMaps.tsNodeToESTreeNodeMap! } }; } diff --git a/tsconfig.json b/tsconfig.json index 568b3c81592a..d11f498502fd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,9 +1,19 @@ { "compilerOptions": { - "target": "es2017", + "allowSyntheticDefaultImports": true, + "allowUnreachableCode": false, + "allowUnusedLabels": false, + "alwaysStrict": true, + "esModuleInterop": true, "module": "commonjs", "moduleResolution": "node", - "esModuleInterop": true, - "strict": true + "noImplicitAny": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "pretty": true, + "strict": true, + "target": "es2017", } } From c651723a59f1230959b1cd93d334c507cfb6cd6a Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 21 Jan 2019 20:01:22 -0800 Subject: [PATCH 02/92] start converting rules --- .../lib/rules/adjacent-overload-signatures.ts | 25 +++--- .../eslint-plugin/src/lib/rules/array-type.ts | 12 +-- .../eslint-plugin/src/lib/rules/ban-types.ts | 8 +- .../eslint-plugin/src/lib/rules/camelcase.ts | 20 ++--- .../src/lib/rules/class-name-casing.ts | 12 ++- .../rules/explicit-function-return-type.ts | 16 +--- .../rules/explicit-member-accessibility.ts | 8 +- .../eslint-plugin/src/lib/rules/indent.ts | 17 ++-- .../src/lib/rules/interface-name-prefix.ts | 48 +++++------ .../src/lib/rules/member-delimiter-style.ts | 28 +++++-- .../src/lib/rules/member-naming.ts | 24 ++++-- .../src/lib/rules/member-ordering.ts | 83 +++++++++++-------- packages/eslint-plugin/tsconfig.json | 2 +- 13 files changed, 157 insertions(+), 146 deletions(-) diff --git a/packages/eslint-plugin/src/lib/rules/adjacent-overload-signatures.ts b/packages/eslint-plugin/src/lib/rules/adjacent-overload-signatures.ts index 0089fa1cc106..62f49a780618 100644 --- a/packages/eslint-plugin/src/lib/rules/adjacent-overload-signatures.ts +++ b/packages/eslint-plugin/src/lib/rules/adjacent-overload-signatures.ts @@ -3,7 +3,6 @@ * @author Patricio Trevino */ -import { Node } from 'estree'; import { Rule } from 'eslint'; import * as util from '../util'; @@ -35,10 +34,9 @@ module.exports = { /** * Gets the name of the member being processed. * @param {ASTNode} member the member being processed. - * @returns {string|null} the name of the member or null if it's a member not relevant to the rule. - * @private + * @returns the name of the member or null if it's a member not relevant to the rule. */ - function getMemberName(member: Node) { + function getMemberName(member): string | null { if (!member) return null; switch (member.type) { @@ -77,22 +75,21 @@ module.exports = { /** * Check the body for overload methods. * @param {ASTNode} node the body to be inspected. - * @returns {void} - * @private */ - function checkBodyForOverloadMethods(node) { + function checkBodyForOverloadMethods(node): void { const members = node.body || node.members; if (members) { - let name; - let index; - let lastName; - const seen = []; + let lastName: string; + const seen: string[] = []; members.forEach(member => { - name = getMemberName(member); + const name = getMemberName(member); + if (name === null) { + return; + } - index = seen.indexOf(name); + const index = seen.indexOf(name!); if (index > -1 && lastName !== name) { context.report({ node: member, @@ -101,7 +98,7 @@ module.exports = { name } }); - } else if (name && index === -1) { + } else if (index === -1) { seen.push(name); } diff --git a/packages/eslint-plugin/src/lib/rules/array-type.ts b/packages/eslint-plugin/src/lib/rules/array-type.ts index 973ac2944960..f77413a4e0df 100644 --- a/packages/eslint-plugin/src/lib/rules/array-type.ts +++ b/packages/eslint-plugin/src/lib/rules/array-type.ts @@ -10,9 +10,8 @@ import * as util from '../util'; /** * Check whatever node can be considered as simple * @param {ASTNode} node the node to be evaluated. - * @returns {*} true or false */ -function isSimpleType(node) { +function isSimpleType(node): boolean { switch (node.type) { case 'Identifier': case 'TSAnyKeyword': @@ -57,9 +56,8 @@ function isSimpleType(node) { /** * Check if node needs parentheses * @param {ASTNode} node the node to be evaluated. - * @returns {*} true or false */ -function typeNeedsParentheses(node) { +function typeNeedsParentheses(node): boolean { switch (node.type) { case 'TSTypeReference': return typeNeedsParentheses(node.typeName); @@ -113,9 +111,8 @@ module.exports = { /** * Check if whitespace is needed before this node * @param {ASTNode} node the node to be evaluated. - * @returns {boolean} true of false */ - function requireWhitespaceBefore(node) { + function requireWhitespaceBefore(node): boolean { const prevToken = sourceCode.getTokenBefore(node); if (node.range[0] - prevToken.range[1] > 0) { @@ -127,9 +124,8 @@ module.exports = { /** * @param {ASTNode} node the node to be evaluated. - * @returns {string} Type used in message */ - function getMessageType(node) { + function getMessageType(node): string { if (node) { if (node.type === 'TSParenthesizedType') { return getMessageType(node.typeAnnotation); diff --git a/packages/eslint-plugin/src/lib/rules/ban-types.ts b/packages/eslint-plugin/src/lib/rules/ban-types.ts index abba5dd2766c..a36f9f181311 100644 --- a/packages/eslint-plugin/src/lib/rules/ban-types.ts +++ b/packages/eslint-plugin/src/lib/rules/ban-types.ts @@ -10,6 +10,10 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ +type TypeErrorConfig = { + message: string; + fixWith?: string; +}; const defaultOptions = [ { types: { @@ -33,7 +37,7 @@ const defaultOptions = [ message: 'Use symbol instead', fixWith: 'symbol' } - } + } as Record } ]; @@ -92,7 +96,7 @@ module.exports = { if (node.name in banedTypes) { let customMessage = ''; const bannedCfgValue = banedTypes[node.name]; - let fixWith = null; + let fixWith: string | null = null; if (typeof bannedCfgValue === 'string') { customMessage += ` ${bannedCfgValue}`; diff --git a/packages/eslint-plugin/src/lib/rules/camelcase.ts b/packages/eslint-plugin/src/lib/rules/camelcase.ts index 6f713b52517e..fefbcd910d2f 100644 --- a/packages/eslint-plugin/src/lib/rules/camelcase.ts +++ b/packages/eslint-plugin/src/lib/rules/camelcase.ts @@ -43,25 +43,23 @@ module.exports = { /** * Checks if a string contains an underscore and isn't all upper-case - * @param {string} name The string to check. - * @returns {boolean} if the string is underscored - * @private + * @param name The string to check. */ - function isUnderscored(name) { + function isUnderscored(name: string): boolean { // if there's an underscore, it might be A_CONSTANT, which is okay return name.indexOf('_') > -1 && name !== name.toUpperCase(); } /** * Checks if a string match the ignore list - * @param {string} name The string to check. - * @returns {boolean} if the string is ignored + * @param name The string to check. + * @returns if the string is ignored * @private */ - function isAllowed(name) { + function isAllowed(name: string): boolean { return ( allow.findIndex( - entry => name === entry || name.match(new RegExp(entry)) + entry => name === entry || name.match(new RegExp(entry)) !== null ) !== -1 ); } @@ -69,10 +67,10 @@ module.exports = { /** * Checks if the the node is a valid TypeScript property type. * @param {Node} node the node to be validated. - * @returns {boolean} true if the node is a TypeScript property type. + * @returns true if the node is a TypeScript property type. * @private */ - function isTSPropertyType(node) { + function isTSPropertyType(node): boolean { if (!node.parent) return false; if (TS_PROPERTY_TYPES.includes(node.parent.type)) return true; @@ -114,7 +112,7 @@ module.exports = { // Let the base rule deal with the rest // eslint-disable-next-line new-cap - rules.Identifier(node); + rules.Identifier!(node); } }; } diff --git a/packages/eslint-plugin/src/lib/rules/class-name-casing.ts b/packages/eslint-plugin/src/lib/rules/class-name-casing.ts index 18ab9263e563..42bdf01f392b 100644 --- a/packages/eslint-plugin/src/lib/rules/class-name-casing.ts +++ b/packages/eslint-plugin/src/lib/rules/class-name-casing.ts @@ -33,20 +33,18 @@ module.exports = { /** * Determine if the identifier name is PascalCased - * @param {string} name The identifier name - * @returns {boolean} Is the name PascalCased? + * @param name The identifier name */ - function isPascalCase(name) { + function isPascalCase(name: string): boolean { return /^[A-Z][0-9A-Za-z]*$/.test(name); } /** * Report a class declaration as invalid - * @param {Node} decl The declaration - * @param {Node} [id=classDecl.id] The name of the declaration - * @returns {undefined} + * @param {Node} decl The declaration + * @param {Node} [id=classDecl.id] The name of the declaration */ - function report(decl, id) { + function report(decl, id): void { const resolvedId = id || decl.id; let friendlyName; diff --git a/packages/eslint-plugin/src/lib/rules/explicit-function-return-type.ts b/packages/eslint-plugin/src/lib/rules/explicit-function-return-type.ts index 4e383421cfd7..964012858e25 100644 --- a/packages/eslint-plugin/src/lib/rules/explicit-function-return-type.ts +++ b/packages/eslint-plugin/src/lib/rules/explicit-function-return-type.ts @@ -49,10 +49,8 @@ module.exports = { /** * Checks if the parent of a function expression is a constructor. * @param {ASTNode} parent The parent of a function expression node - * @returns {boolean} `true` if the parent is a constructor - * @private */ - function isConstructor(parent) { + function isConstructor(parent): boolean { return ( parent.type === 'MethodDefinition' && parent.kind === 'constructor' ); @@ -61,20 +59,16 @@ module.exports = { /** * Checks if the parent of a function expression is a setter. * @param {ASTNode} parent The parent of a function expression node - * @returns {boolean} `true` if the parent is a setter - * @private */ - function isSetter(parent) { + function isSetter(parent): boolean { return parent.type === 'MethodDefinition' && parent.kind === 'set'; } /** * Checks if a function declaration/expression has a return type. * @param {ASTNode} node The node representing a function. - * @returns {void} - * @private */ - function checkFunctionReturnType(node) { + function checkFunctionReturnType(node): void { if ( !node.returnType && !isConstructor(node.parent) && @@ -91,10 +85,8 @@ module.exports = { /** * Checks if a function declaration/expression has a return type. * @param {ASTNode} node The node representing a function. - * @returns {void} - * @private */ - function checkFunctionExpressionReturnType(node) { + function checkFunctionExpressionReturnType(node): void { if ( options.allowExpressions && node.parent.type !== 'VariableDeclarator' && diff --git a/packages/eslint-plugin/src/lib/rules/explicit-member-accessibility.ts b/packages/eslint-plugin/src/lib/rules/explicit-member-accessibility.ts index 616a18259e48..89543c305689 100644 --- a/packages/eslint-plugin/src/lib/rules/explicit-member-accessibility.ts +++ b/packages/eslint-plugin/src/lib/rules/explicit-member-accessibility.ts @@ -32,10 +32,8 @@ module.exports = { /** * Checks if a method declaration has an accessibility modifier. * @param {ASTNode} methodDefinition The node representing a MethodDefinition. - * @returns {void} - * @private */ - function checkMethodAccessibilityModifier(methodDefinition) { + function checkMethodAccessibilityModifier(methodDefinition): void { if ( !methodDefinition.accessibility && util.isTypescript(context.getFilename()) @@ -54,10 +52,8 @@ module.exports = { /** * Checks if property has an accessibility modifier. * @param {ASTNode} classProperty The node representing a ClassProperty. - * @returns {void} - * @private */ - function checkPropertyAccessibilityModifier(classProperty) { + function checkPropertyAccessibilityModifier(classProperty): void { if ( !classProperty.accessibility && util.isTypescript(context.getFilename()) diff --git a/packages/eslint-plugin/src/lib/rules/indent.ts b/packages/eslint-plugin/src/lib/rules/indent.ts index 3b08b3606831..92d7d4c7e53d 100644 --- a/packages/eslint-plugin/src/lib/rules/indent.ts +++ b/packages/eslint-plugin/src/lib/rules/indent.ts @@ -3,6 +3,7 @@ * @author Patricio Trevino */ +import * as ESTree from 'estree'; import { Rule } from 'eslint'; import baseRule from 'eslint/lib/rules/indent'; import * as util from '../util'; @@ -101,14 +102,14 @@ module.exports = Object.assign({}, baseRule, { url: util.metaDocsUrl('indent') }, fixable: 'whitespace', - schema: baseRule.meta.schema, - messages: baseRule.meta.messages + schema: baseRule.meta!.schema, + messages: baseRule.meta!.messages }, create(context: Rule.RuleContext) { // because we extend the base rule, have to update opts on the context // the context defines options as readonly though... - const contextWithDefaults = Object.create(context, { + const contextWithDefaults: Rule.RuleContext = Object.create(context, { options: { writable: false, configurable: false, @@ -120,11 +121,11 @@ module.exports = Object.assign({}, baseRule, { /** * Converts from a TSPropertySignature to a Property - * @param {Object} node a TSPropertySignature node - * @param {string} [type] the type to give the new node + * @param {ASTNode} node a TSPropertySignature node + * @param [type] the type to give the new node * @returns {Object} a Property node */ - function TSPropertySignatureToProperty(node, type = 'Property') { + function TSPropertySignatureToProperty(node, type: string = 'Property') { return { type, key: node.key, @@ -200,7 +201,9 @@ module.exports = Object.assign({}, baseRule, { // transform it to an ObjectExpression return rules['ObjectExpression, ObjectPattern']({ type: 'ObjectExpression', - properties: node.members.map(TSPropertySignatureToProperty), + properties: node.members.map(member => + TSPropertySignatureToProperty(member) + ), // location data parent: node.parent, diff --git a/packages/eslint-plugin/src/lib/rules/interface-name-prefix.ts b/packages/eslint-plugin/src/lib/rules/interface-name-prefix.ts index fc695a653481..165b57003e11 100644 --- a/packages/eslint-plugin/src/lib/rules/interface-name-prefix.ts +++ b/packages/eslint-plugin/src/lib/rules/interface-name-prefix.ts @@ -39,11 +39,9 @@ module.exports = { /** * Checks if a string is prefixed with "I". - * @param {string} name The string to check - * @returns {boolean} true if it is prefixed with "I" - * @private + * @param name The string to check */ - function isPrefixedWithI(name) { + function isPrefixedWithI(name: string): boolean { if (typeof name !== 'string') { return false; } @@ -51,35 +49,27 @@ module.exports = { return /^I[A-Z]/.test(name); } - /** - * Checks if interface is prefixed with "I". - * @param {ASTNode} interfaceNode The node representing an Interface. - * @returns {void} - * @private - */ - function checkInterfacePrefix(interfaceNode) { - if (never) { - if (isPrefixedWithI(interfaceNode.id.name)) { - context.report({ - node: interfaceNode.id, - message: 'Interface name must not be prefixed with "I".' - }); - } - } else { - if (!isPrefixedWithI(interfaceNode.id.name)) { - context.report({ - node: interfaceNode.id, - message: 'Interface name must be prefixed with "I".' - }); - } - } - } - //---------------------------------------------------------------------- // Public //---------------------------------------------------------------------- return { - TSInterfaceDeclaration: checkInterfacePrefix + TSInterfaceDeclaration(node): void { + if (never) { + if (isPrefixedWithI(node.id.name)) { + context.report({ + node: node.id, + message: 'Interface name must not be prefixed with "I".' + }); + } + } else { + if (!isPrefixedWithI(node.id.name)) { + context.report({ + node: node.id, + message: 'Interface name must be prefixed with "I".' + }); + } + } + } }; } }; diff --git a/packages/eslint-plugin/src/lib/rules/member-delimiter-style.ts b/packages/eslint-plugin/src/lib/rules/member-delimiter-style.ts index ef34066aaf42..8c3fa3c96aed 100644 --- a/packages/eslint-plugin/src/lib/rules/member-delimiter-style.ts +++ b/packages/eslint-plugin/src/lib/rules/member-delimiter-style.ts @@ -11,7 +11,24 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -const defaultOptions = [ +type Delimiter = 'comma' | 'none' | 'semi'; +type BaseOptions = { + multiline: { + delimiter: Delimiter; + requireLast: boolean; + }; + singleline: { + delimiter: Delimiter; + requireLast: boolean; + }; +}; +type Options = BaseOptions & { + overrides?: { + typeLiteral?: BaseOptions; + interface?: BaseOptions; + }; +}; +const defaultOptions: Options[] = [ { multiline: { delimiter: 'semi', @@ -112,10 +129,9 @@ module.exports = { function checkLastToken(member, opts, isLast) { /** * Resolves the boolean value for the given setting enum value - * @param {"semi" | "comma" | "none"} type the option name - * @returns {boolean} the resolved value + * @param type the option name */ - function getOption(type) { + function getOption(type: Delimiter): boolean { if (isLast && !opts.requireLast) { // only turn the option on if its expecting no delimiter for the last member return type === 'none'; @@ -194,10 +210,8 @@ module.exports = { /** * Check the member separator being used matches the delimiter. * @param {ASTNode} node the node to be evaluated. - * @returns {void} - * @private */ - function checkMemberSeparatorStyle(node) { + function checkMemberSeparatorStyle(node): void { const isInterface = node.type === 'TSInterfaceBody'; const isSingleLine = node.loc.start.line === node.loc.end.line; diff --git a/packages/eslint-plugin/src/lib/rules/member-naming.ts b/packages/eslint-plugin/src/lib/rules/member-naming.ts index 1b3660ee57c1..5d707aa59888 100644 --- a/packages/eslint-plugin/src/lib/rules/member-naming.ts +++ b/packages/eslint-plugin/src/lib/rules/member-naming.ts @@ -10,7 +10,14 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -const defaultOptions = [{}]; +type Options = { + private?: T; + protected?: T; + public?: T; +}; +type Modifiers = keyof Options; + +const defaultOptions: Options[] = [{}]; module.exports = { meta: { @@ -50,11 +57,14 @@ module.exports = { create(context: Rule.RuleContext) { const config = util.applyDefault(defaultOptions, context.options)[0]; - const conventions = Object.keys(config).reduce((acc, accessibility) => { - acc[accessibility] = new RegExp(config[accessibility]); + const conventions = (Object.keys(config) as Modifiers[]).reduce( + (acc, accessibility) => { + acc[accessibility] = new RegExp(config[accessibility]!); - return acc; - }, {}); + return acc; + }, + {} as Options + ); //---------------------------------------------------------------------- // Helpers @@ -67,9 +77,9 @@ module.exports = { * @returns {void} * @private */ - function validateName(node) { + function validateName(node): void { const name = node.key.name; - const accessibility = node.accessibility || 'public'; + const accessibility: Modifiers = node.accessibility || 'public'; const convention = conventions[accessibility]; if (!convention || convention.test(name)) return; diff --git a/packages/eslint-plugin/src/lib/rules/member-ordering.ts b/packages/eslint-plugin/src/lib/rules/member-ordering.ts index 6d1e6f8e85ad..ab1d289fff50 100644 --- a/packages/eslint-plugin/src/lib/rules/member-ordering.ts +++ b/packages/eslint-plugin/src/lib/rules/member-ordering.ts @@ -28,10 +28,19 @@ const schemaOptions = ['field', 'method', 'constructor'].reduce( return options; }, - [] + [] as string[] ); -const defaultOptions = [ +type OrderConfig = string[] | 'never'; +type Options = { + default: OrderConfig; + classes?: OrderConfig; + classExpressions?: OrderConfig; + interfaces?: OrderConfig; + typeLiterals?: OrderConfig; +}; + +const defaultOptions: Options[] = [ { default: [ 'public-static-field', @@ -173,10 +182,8 @@ module.exports = { /** * Determines if `node` should be processed as a method instead of a field. * @param {ASTNode} node the node to be inspected. - * @returns {boolean} `true` if node should be processed as a method; `false` for fields. - * @private */ - function shouldBeProcessedAsMethod(node) { + function shouldBeProcessedAsMethod(node): boolean { // check for bound methods in ClassProperty nodes. return node.value && functionExpressions.indexOf(node.value.type) > -1; } @@ -184,10 +191,8 @@ module.exports = { /** * Gets the node type. * @param {ASTNode} node the node to be evaluated. - * @returns {string|null} the type of the node. - * @private */ - function getNodeType(node) { + function getNodeType(node): string | null { // TODO: add missing TSCallSignatureDeclaration switch (node.type) { case 'MethodDefinition': @@ -207,10 +212,8 @@ module.exports = { /** * Gets the member name based on the member type. * @param {ASTNode} node the node to be evaluated. - * @returns {string|null} the name of the member. - * @private */ - function getMemberName(node) { + function getMemberName(node): string | null { switch (node.type) { case 'ClassProperty': case 'MethodDefinition': @@ -232,17 +235,15 @@ module.exports = { * - If there is no order for accessibility-scope-type, then strip out the accessibility. * - If there is no order for scope-type, then strip out the scope. * - If there is no order for type, then return -1 - * @param {Array} names the valid names to be validated. - * @param {Array} order the current order to be validated. - * @returns {number} the rank of the method definition in the given order. - * @private + * @param names the valid names to be validated. + * @param order the current order to be validated. */ - function getRankOrder(names, order) { + function getRankOrder(names: string[], order: string[]): number { let rank = -1; const stack = names.slice(); while (stack.length > 0 && rank === -1) { - rank = order.indexOf(stack.shift()); + rank = order.indexOf(stack.shift()!); } return rank; @@ -251,13 +252,20 @@ module.exports = { /** * Gets the rank of the node given the order. * @param {ASTNode} node the node to be evaluated. - * @param {Array} order the current order to be validated. - * @param {boolean} supportsModifiers a flag indicating whether the type supports modifiers or not. - * @returns {number} the rank of the node. - * @private + * @param order the current order to be validated. + * @param supportsModifiers a flag indicating whether the type supports modifiers or not. */ - function getRank(node, order, supportsModifiers) { + function getRank( + node, + order: string[], + supportsModifiers: boolean + ): number { const type = getNodeType(node); + if (type === null) { + // shouldn't happen but just in case, put it on the end + return Number.MAX_SAFE_INTEGER; + } + const scope = node.static ? 'static' : 'instance'; const accessibility = node.accessibility || 'public'; @@ -290,13 +298,16 @@ module.exports = { * and considering that a public-instance-method has already been declared, so ranks contains * public-instance-method, then the lowest possible rank for public-static-method is * public-instance-method. - * @param {Array} ranks the existing ranks in the object. - * @param {number} target the target rank. - * @param {Array} order the current order to be validated. - * @returns {string} the name of the lowest possible rank without dashes (-). - * @private + * @param ranks the existing ranks in the object. + * @param target the target rank. + * @param order the current order to be validated. + * @returns the name of the lowest possible rank without dashes (-). */ - function getLowestRank(ranks, target, order) { + function getLowestRank( + ranks: number[], + target: number, + order: string[] + ): string { let lowest = ranks[ranks.length - 1]; ranks.forEach(rank => { @@ -310,15 +321,17 @@ module.exports = { /** * Validates each member rank. - * @param {Array} members the members to be validated. - * @param {(Array|string)} order the current order to be validated. - * @param {boolean} supportsModifiers a flag indicating whether the type supports modifiers or not. - * @returns {void} - * @private + * @param {Array} members the members to be validated. + * @param order the current order to be validated. + * @param supportsModifiers a flag indicating whether the type supports modifiers or not. */ - function validateMembers(members, order, supportsModifiers) { + function validateMembers( + members, + order: OrderConfig, + supportsModifiers: boolean + ): void { if (members && order !== 'never') { - const previousRanks = []; + const previousRanks: number[] = []; members.forEach(member => { const rank = getRank(member, order, supportsModifiers); diff --git a/packages/eslint-plugin/tsconfig.json b/packages/eslint-plugin/tsconfig.json index 8b51ca27bda3..d8a23e63b590 100644 --- a/packages/eslint-plugin/tsconfig.json +++ b/packages/eslint-plugin/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "declaration": true, + "declaration": false, "outDir": "./dist" }, "include": ["src", "typings"] From 1714d3b4c5f5e21969957e2cfe1db7b445d95686 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 21 Jan 2019 21:06:47 -0800 Subject: [PATCH 03/92] first pass type conversion done --- .../src/lib/rules/no-inferrable-types.ts | 15 +-- .../src/lib/rules/no-misused-new.ts | 7 +- .../rules/no-object-literal-type-assertion.ts | 3 +- .../src/lib/rules/no-parameter-properties.ts | 4 +- .../src/lib/rules/no-this-alias.ts | 2 +- .../lib/rules/no-triple-slash-reference.ts | 4 +- .../src/lib/rules/no-type-alias.ts | 74 +++++++-------- .../src/lib/rules/no-unused-vars.ts | 9 +- .../src/lib/rules/no-use-before-define.ts | 95 ++++++++++--------- .../src/lib/rules/type-annotation-spacing.ts | 4 +- 10 files changed, 104 insertions(+), 113 deletions(-) diff --git a/packages/eslint-plugin/src/lib/rules/no-inferrable-types.ts b/packages/eslint-plugin/src/lib/rules/no-inferrable-types.ts index 4902375539f1..28be699b5bb1 100644 --- a/packages/eslint-plugin/src/lib/rules/no-inferrable-types.ts +++ b/packages/eslint-plugin/src/lib/rules/no-inferrable-types.ts @@ -55,9 +55,8 @@ module.exports = { * Returns whether a node has an inferrable value or not * @param {ASTNode} node the node to check * @param {ASTNode} init the initializer - * @returns {boolean} whether the node has an inferrable type */ - function isInferrable(node, init) { + function isInferrable(node, init): boolean { if (node.type !== 'TSTypeAnnotation' || !node.typeAnnotation) { return false; } @@ -103,9 +102,8 @@ module.exports = { * @param {ASTNode} node the node being visited * @param {ASTNode} typeNode the type annotation node * @param {ASTNode} initNode the initializer node - * @returns {void} */ - function reportInferrableType(node, typeNode, initNode) { + function reportInferrableType(node, typeNode, initNode): void { if (!typeNode || !initNode || !typeNode.typeAnnotation) { return; } @@ -136,9 +134,8 @@ module.exports = { /** * Visits variables * @param {ASTNode} node the node to be visited - * @returns {void} */ - function inferrableVariableVisitor(node) { + function inferrableVariableVisitor(node): void { if (!node.id) { return; } @@ -148,9 +145,8 @@ module.exports = { /** * Visits parameters * @param {ASTNode} node the node to be visited - * @returns {void} */ - function inferrableParameterVisitor(node) { + function inferrableParameterVisitor(node): void { if (ignoreParameters || !node.params) { return; } @@ -167,9 +163,8 @@ module.exports = { /** * Visits properties * @param {ASTNode} node the node to be visited - * @returns {void} */ - function inferrablePropertyVisitor(node) { + function inferrablePropertyVisitor(node): void { // We ignore `readonly` because of Microsoft/TypeScript#14416 // Essentially a readonly property without a type // will result in its value being the type, leading to diff --git a/packages/eslint-plugin/src/lib/rules/no-misused-new.ts b/packages/eslint-plugin/src/lib/rules/no-misused-new.ts index 8d0242b2d4ca..d8d9c7d96d82 100644 --- a/packages/eslint-plugin/src/lib/rules/no-misused-new.ts +++ b/packages/eslint-plugin/src/lib/rules/no-misused-new.ts @@ -34,9 +34,9 @@ module.exports = { create(context: Rule.RuleContext) { /** * @param {ASTNode} node type to be inspected. - * @returns {string|null} name of simple type or null + * @returns name of simple type or null */ - function getTypeReferenceName(node) { + function getTypeReferenceName(node): string | null { if (node) { switch (node.type) { case 'TSTypeAnnotation': @@ -55,9 +55,8 @@ module.exports = { /** * @param {ASTNode} parent parent node. * @param {ASTNode} returnType type to be compared - * @returns {boolean} returns true if type is parent type */ - function isMatchingParentType(parent, returnType) { + function isMatchingParentType(parent, returnType): boolean { if (parent && parent.id && parent.id.type === 'Identifier') { return getTypeReferenceName(returnType) === parent.id.name; } diff --git a/packages/eslint-plugin/src/lib/rules/no-object-literal-type-assertion.ts b/packages/eslint-plugin/src/lib/rules/no-object-literal-type-assertion.ts index 8d644ba9b9a8..336a526b8283 100644 --- a/packages/eslint-plugin/src/lib/rules/no-object-literal-type-assertion.ts +++ b/packages/eslint-plugin/src/lib/rules/no-object-literal-type-assertion.ts @@ -35,9 +35,8 @@ module.exports = { /** * Check whatever node should be reported * @param {ASTNode} node the node to be evaluated. - * @returns {*} true or false */ - function checkType(node) { + function checkType(node): boolean { if (node) { switch (node.type) { case 'TSAnyKeyword': diff --git a/packages/eslint-plugin/src/lib/rules/no-parameter-properties.ts b/packages/eslint-plugin/src/lib/rules/no-parameter-properties.ts index 90e5721d5e1e..e2b216f9040c 100644 --- a/packages/eslint-plugin/src/lib/rules/no-parameter-properties.ts +++ b/packages/eslint-plugin/src/lib/rules/no-parameter-properties.ts @@ -62,10 +62,8 @@ module.exports = { /** * Gets the modifiers of `node`. * @param {ASTNode} node the node to be inspected. - * @returns {string} the modifiers of node - * @private */ - function getModifiers(node) { + function getModifiers(node): string { const modifiers = []; modifiers.push(node.accessibility); diff --git a/packages/eslint-plugin/src/lib/rules/no-this-alias.ts b/packages/eslint-plugin/src/lib/rules/no-this-alias.ts index c4aa6e7b0038..703e32abf385 100644 --- a/packages/eslint-plugin/src/lib/rules/no-this-alias.ts +++ b/packages/eslint-plugin/src/lib/rules/no-this-alias.ts @@ -13,7 +13,7 @@ import * as util from '../util'; const defaultOptions = [ { allowDestructuring: false, - allowedNames: [] + allowedNames: [] as string[] } ]; diff --git a/packages/eslint-plugin/src/lib/rules/no-triple-slash-reference.ts b/packages/eslint-plugin/src/lib/rules/no-triple-slash-reference.ts index 7678dfa1eed5..a2d43ab0cfb0 100644 --- a/packages/eslint-plugin/src/lib/rules/no-triple-slash-reference.ts +++ b/packages/eslint-plugin/src/lib/rules/no-triple-slash-reference.ts @@ -37,10 +37,8 @@ module.exports = { /** * Checks if property has an accessibility modifier. * @param {ASTNode} program The node representing a Program. - * @returns {void} - * @private */ - function checkTripleSlashReference(program) { + function checkTripleSlashReference(program): void { const commentsBefore = sourceCode.getCommentsBefore(program); commentsBefore.forEach(comment => { diff --git a/packages/eslint-plugin/src/lib/rules/no-type-alias.ts b/packages/eslint-plugin/src/lib/rules/no-type-alias.ts index 090f721b2600..556c91e7f8f1 100644 --- a/packages/eslint-plugin/src/lib/rules/no-type-alias.ts +++ b/packages/eslint-plugin/src/lib/rules/no-type-alias.ts @@ -107,10 +107,8 @@ module.exports = { /** * Determines if the given node is a union or an intersection. * @param {TSNode} node the node to be evaluated. - * @returns {boolean} true when node if a union or intersection. - * @private */ - function isComposition(node) { + function isComposition(node): boolean { return ( node && (node.type === 'TSUnionType' || node.type === 'TSIntersectionType') @@ -119,13 +117,15 @@ module.exports = { /** * Determines if the composition type is supported by the allowed flags. - * @param {boolean} isTopLevel a flag indicating this is the top level node. - * @param {string} compositionType the composition type (either TSUnionType or TSIntersectionType) - * @param {string} allowed the currently allowed flags. - * @returns {boolean} true if the composition type supported by the allowed flags. - * @private + * @param isTopLevel a flag indicating this is the top level node. + * @param compositionType the composition type (either TSUnionType or TSIntersectionType) + * @param allowed the currently allowed flags. */ - function isSupportedComposition(isTopLevel, compositionType, allowed) { + function isSupportedComposition( + isTopLevel: boolean, + compositionType: string | undefined, + allowed: string + ): boolean { return ( compositions.indexOf(allowed) === -1 || (!isTopLevel && @@ -139,10 +139,8 @@ module.exports = { /** * Determines if the given node is an alias type (keywords, arrays, type references and constants). * @param {TSNode} node the node to be evaluated. - * @returns {boolean} true when the node is an alias type. - * @private */ - function isAlias(node) { + function isAlias(node): boolean { return ( node && (/Keyword$/.test(node.type) || aliasTypes.indexOf(node.type) > -1) @@ -152,44 +150,41 @@ module.exports = { /** * Determines if the given node is a callback type. * @param {TSNode} node the node to be evaluated. - * @returns {boolean} true when the node is a callback type. - * @private */ - function isCallback(node) { + function isCallback(node): boolean { return node && node.type === 'TSFunctionType'; } /** * Determines if the given node is a literal type (objects). * @param {TSNode} node the node to be evaluated. - * @returns {boolean} true when the node is a literal type (object). - * @private */ - function isLiteral(node) { + function isLiteral(node): boolean { return node && node.type === 'TSTypeLiteral'; } /** * Determines if the given node is a mapped type. * @param {TSNode} node the node to be evaluated. - * @returns {boolean} true when the node is a mapped type. - * @private */ - function isMappedType(node) { + function isMappedType(node): boolean { return node && node.type === 'TSMappedType'; } /** * Gets the message to be displayed based on the node type and whether the node is a top level declaration. - * @param {Object} node the location - * @param {string} compositionType the type of composition this alias is part of (undefined if not + * @param {ASTNode} node the location + * @param compositionType the type of composition this alias is part of (undefined if not * part of a composition) - * @param {boolean} isRoot a flag indicating we are dealing with the top level declaration. - * @param {string} type the kind of type alias being validated. - * @returns {string} the message to be displayed. - * @private + * @param isRoot a flag indicating we are dealing with the top level declaration. + * @param type the kind of type alias being validated. */ - function getMessage(node, compositionType, isRoot, type) { + function getMessage( + node, + compositionType: string | undefined, + isRoot: boolean, + type?: string + ): Rule.ReportDescriptor { if (isRoot) { return { node, @@ -206,7 +201,7 @@ module.exports = { data: { compositionType: compositionType === 'TSUnionType' ? 'union' : 'intersection', - typeName: util.upperCaseFirst(type) + typeName: util.upperCaseFirst(type!) } }; } @@ -214,13 +209,15 @@ module.exports = { /** * Validates the node looking for aliases, callbacks and literals. * @param {TSNode} node the node to be validated. - * @param {boolean} isTopLevel a flag indicating this is the top level node. - * @param {boolean} compositionType the type of composition this alias is part of (undefined if not + * @param isTopLevel a flag indicating this is the top level node. + * @param compositionType the type of composition this alias is part of (undefined if not * part of a composition) - * @returns {void} - * @private */ - function validateTypeAliases(node, isTopLevel, compositionType) { + function validateTypeAliases( + node, + isTopLevel: boolean, + compositionType?: string + ): void { if (isAlias(node)) { if ( allowAliases === 'never' || @@ -278,15 +275,14 @@ module.exports = { /** * Validates the node looking for compositions, aliases, callbacks and literals. * @param {TSNode} node the node to be validated. - * @param {boolean} isTopLevel a flag indicating this is the top level node. - * @returns {void} + * @param isTopLevel a flag indicating this is the top level node. * @private */ - function validateNode(node, isTopLevel) { + function validateNode(node): void { if (isComposition(node)) { validateCompositions(node); } else { - validateTypeAliases(node, isTopLevel); + validateTypeAliases(node, true); } } @@ -295,7 +291,7 @@ module.exports = { //---------------------------------------------------------------------- return { TSTypeAliasDeclaration(node) { - validateNode(node.typeAnnotation, true); + validateNode(node.typeAnnotation); } }; } diff --git a/packages/eslint-plugin/src/lib/rules/no-unused-vars.ts b/packages/eslint-plugin/src/lib/rules/no-unused-vars.ts index 43b8ead8bcd7..139eee1e8f71 100644 --- a/packages/eslint-plugin/src/lib/rules/no-unused-vars.ts +++ b/packages/eslint-plugin/src/lib/rules/no-unused-vars.ts @@ -5,6 +5,7 @@ import { Rule } from 'eslint'; import baseRule from 'eslint/lib/rules/no-unused-vars'; +import { Identifier } from 'estree'; import * as util from '../util'; //------------------------------------------------------------------------------ @@ -30,10 +31,9 @@ module.exports = Object.assign({}, baseRule, { /** * Mark this function parameter as used - * @param {Identifier} node The node currently being traversed - * @returns {void} + * @param node The node currently being traversed */ - function markThisParameterAsUsed(node) { + function markThisParameterAsUsed(node: Identifier): void { if (node.name) { const variable = context .getScope() @@ -48,9 +48,8 @@ module.exports = Object.assign({}, baseRule, { /** * Mark heritage clause as used * @param node The node currently being traversed - * @returns {void} */ - function markHeritageAsUsed(node) { + function markHeritageAsUsed(node): void { switch (node.type) { case 'Identifier': context.markVariableAsUsed(node.name); diff --git a/packages/eslint-plugin/src/lib/rules/no-use-before-define.ts b/packages/eslint-plugin/src/lib/rules/no-use-before-define.ts index 6245f024286a..8f35008ef2ad 100644 --- a/packages/eslint-plugin/src/lib/rules/no-use-before-define.ts +++ b/packages/eslint-plugin/src/lib/rules/no-use-before-define.ts @@ -6,7 +6,7 @@ * @author Jed Fox */ -import { Rule } from 'eslint'; +import { Rule, Scope } from 'eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ @@ -16,13 +16,19 @@ import * as util from '../util'; const SENTINEL_TYPE = /^(?:(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|CatchClause|ImportDeclaration|ExportNamedDeclaration)$/; const FOR_IN_OF_TYPE = /^For(?:In|Of)Statement$/; +type Options = { + functions?: boolean; + classes?: boolean; + variables?: boolean; + typedefs?: boolean; +}; + /** * Parses a given value as options. * * @param {any} options - A value to parse. - * @returns {Object} The parsed options. */ -function parseOptions(options) { +function parseOptions(options: string | Options | null): Options { let functions = true; let classes = true; let variables = true; @@ -41,31 +47,30 @@ function parseOptions(options) { } /** - * @param {Scope} scope - a scope to check - * @returns {boolean} `true` if the scope is toplevel + * Checks whether or not a given scope is a top level scope. + * @param scope - a scope to check */ -function isTopLevelScope(scope) { +function isTopLevelScope(scope: Scope.Scope): boolean { return scope.type === 'module' || scope.type === 'global'; } /** * Checks whether or not a given variable is a function declaration. - * - * @param {eslint-scope.Variable} variable - A variable to check. - * @returns {boolean} `true` if the variable is a function declaration. + * @param variable - A variable to check. */ -function isFunction(variable) { +function isFunction(variable: Scope.Variable): boolean { return variable.defs[0].type === 'FunctionName'; } /** * Checks whether or not a given variable is a class declaration in an upper function scope. - * - * @param {eslint-scope.Variable} variable - A variable to check. - * @param {eslint-scope.Reference} reference - A reference to check. - * @returns {boolean} `true` if the variable is a class declaration. + * @param variable - A variable to check. + * @param reference - A reference to check. */ -function isOuterClass(variable, reference) { +function isOuterClass( + variable: Scope.Variable, + reference: Scope.Reference +): boolean { if (variable.defs[0].type !== 'ClassName') { return false; } @@ -82,11 +87,13 @@ function isOuterClass(variable, reference) { /** * Checks whether or not a given variable is a variable declaration in an upper function scope. - * @param {eslint-scope.Variable} variable - A variable to check. - * @param {eslint-scope.Reference} reference - A reference to check. - * @returns {boolean} `true` if the variable is a variable declaration. + * @param variable - A variable to check. + * @param reference - A reference to check. */ -function isOuterVariable(variable, reference) { +function isOuterVariable( + variable: Scope.Variable, + reference: Scope.Reference +): boolean { if (variable.defs[0].type !== 'Variable') { return false; } @@ -103,13 +110,14 @@ function isOuterVariable(variable, reference) { /** * Checks whether or not a given variable is a type declaration. - * @param {eslint-scope.Variable} variable - A type to check. - * @returns {boolean} `true` if the variable is a type. + * @param variable - A type to check. */ -function isType(variable) { - return ( - variable.defs[0].type === 'Variable' && - variable.defs[0].parent.kind === 'type' +function isType(variable: Scope.Variable): boolean { + const def = variable.defs[0]; + return !!( + def.type === 'Variable' && + def.parent && + def.parent.kind === 'type' ); } @@ -117,10 +125,9 @@ function isType(variable) { * Checks whether or not a given location is inside of the range of a given node. * * @param {ASTNode} node - An node to check. - * @param {number} location - A location to check. - * @returns {boolean} `true` if the location is inside of the range of the node. + * @param location - A location to check. */ -function isInRange(node, location) { +function isInRange(node, location: number): boolean { return node && node.range[0] <= location && location <= node.range[1]; } @@ -135,11 +142,13 @@ function isInRange(node, location) { * for (var a in a) {} * for (var a of a) {} * - * @param {Variable} variable - A variable to check. - * @param {Reference} reference - A reference to check. - * @returns {boolean} `true` if the reference is inside of the initializers. + * @param variable - A variable to check. + * @param reference - A reference to check. */ -function isInInitializer(variable, reference) { +function isInInitializer( + variable: Scope.Variable, + reference: Scope.Reference +): boolean { if (variable.scope !== reference.from) { return false; } @@ -223,22 +232,24 @@ module.exports = { /** * Determines whether a given use-before-define case should be reported according to the options. - * @param {eslint-scope.Variable} variable The variable that gets used before being defined - * @param {eslint-scope.Reference} reference The reference to the variable - * @returns {boolean} `true` if the usage should be reported + * @param variable The variable that gets used before being defined + * @param reference The reference to the variable */ - function isForbidden(variable, reference) { + function isForbidden( + variable: Scope.Variable, + reference: Scope.Reference + ): boolean { if (isFunction(variable)) { - return options.functions; + return !!options.functions; } if (isOuterClass(variable, reference)) { - return options.classes; + return !!options.classes; } if (isType(variable) && !options.typedefs) { return false; } if (isOuterVariable(variable, reference)) { - return options.variables; + return !!options.variables; } return true; } @@ -246,10 +257,8 @@ module.exports = { /** * Finds and validates all variables in a given scope. * @param {Scope} scope The scope object. - * @returns {void} - * @private */ - function findVariablesInScope(scope) { + function findVariablesInScope(scope: Scope.Scope): void { scope.references.forEach(reference => { const variable = reference.resolved; @@ -263,7 +272,7 @@ module.exports = { reference.init || !variable || variable.identifiers.length === 0 || - (variable.identifiers[0].range[1] < reference.identifier.range[1] && + (variable.identifiers[0].range![1] < reference.identifier.range![1] && !isInInitializer(variable, reference)) || !isForbidden(variable, reference) ) { diff --git a/packages/eslint-plugin/src/lib/rules/type-annotation-spacing.ts b/packages/eslint-plugin/src/lib/rules/type-annotation-spacing.ts index 724cc7849fd8..f4f2b068ceef 100644 --- a/packages/eslint-plugin/src/lib/rules/type-annotation-spacing.ts +++ b/packages/eslint-plugin/src/lib/rules/type-annotation-spacing.ts @@ -84,10 +84,8 @@ module.exports = { * Checks if there's proper spacing around type annotations (no space * before colon, one space after). * @param {ASTNode} typeAnnotation The TSTypeAnnotation node. - * @returns {void} - * @private */ - function checkTypeAnnotationSpacing(typeAnnotation) { + function checkTypeAnnotationSpacing(typeAnnotation): void { const nextToken = typeAnnotation; const punctuatorTokenEnd = sourceCode.getTokenBefore(nextToken); let punctuatorTokenStart = punctuatorTokenEnd; From bcb3288e50e6434b348813374168d41011708ed4 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 21 Jan 2019 21:42:42 -0800 Subject: [PATCH 04/92] es6 exports --- .../src/{lib => }/configs/recommended.json | 0 packages/eslint-plugin/src/index.ts | 9 +++++---- .../src/lib/rules/adjacent-overload-signatures.ts | 3 ++- packages/eslint-plugin/src/lib/rules/array-type.ts | 3 ++- packages/eslint-plugin/src/lib/rules/ban-types.ts | 7 ++++--- packages/eslint-plugin/src/lib/rules/camelcase.ts | 3 ++- .../eslint-plugin/src/lib/rules/class-name-casing.ts | 3 ++- .../src/lib/rules/explicit-function-return-type.ts | 3 ++- .../src/lib/rules/explicit-member-accessibility.ts | 3 ++- .../src/lib/rules/generic-type-naming.ts | 3 ++- packages/eslint-plugin/src/lib/rules/indent.ts | 4 ++-- .../src/lib/rules/interface-name-prefix.ts | 3 ++- .../src/lib/rules/member-delimiter-style.ts | 11 ++++++----- packages/eslint-plugin/src/lib/rules/member-naming.ts | 7 ++++--- .../eslint-plugin/src/lib/rules/member-ordering.ts | 7 ++++--- .../src/lib/rules/no-angle-bracket-type-assertion.ts | 3 ++- .../src/lib/rules/no-array-constructor.ts | 3 ++- .../eslint-plugin/src/lib/rules/no-empty-interface.ts | 3 ++- .../eslint-plugin/src/lib/rules/no-explicit-any.ts | 3 ++- .../src/lib/rules/no-extraneous-class.ts | 3 ++- .../src/lib/rules/no-inferrable-types.ts | 3 ++- .../eslint-plugin/src/lib/rules/no-misused-new.ts | 3 ++- packages/eslint-plugin/src/lib/rules/no-namespace.ts | 3 ++- .../src/lib/rules/no-non-null-assertion.ts | 3 ++- .../src/lib/rules/no-object-literal-type-assertion.ts | 3 ++- .../src/lib/rules/no-parameter-properties.ts | 3 ++- packages/eslint-plugin/src/lib/rules/no-this-alias.ts | 3 ++- .../src/lib/rules/no-triple-slash-reference.ts | 3 ++- packages/eslint-plugin/src/lib/rules/no-type-alias.ts | 3 ++- .../eslint-plugin/src/lib/rules/no-unused-vars.ts | 3 ++- .../src/lib/rules/no-use-before-define.ts | 7 ++++--- .../eslint-plugin/src/lib/rules/no-var-requires.ts | 3 ++- .../eslint-plugin/src/lib/rules/prefer-interface.ts | 3 ++- .../src/lib/rules/prefer-namespace-keyword.ts | 3 ++- .../src/lib/rules/type-annotation-spacing.ts | 3 ++- packages/eslint-plugin/src/lib/util.ts | 2 +- packages/eslint-plugin/tsconfig.json | 3 ++- packages/typescript-estree/src/parser.ts | 4 ++-- 38 files changed, 88 insertions(+), 54 deletions(-) rename packages/eslint-plugin/src/{lib => }/configs/recommended.json (100%) diff --git a/packages/eslint-plugin/src/lib/configs/recommended.json b/packages/eslint-plugin/src/configs/recommended.json similarity index 100% rename from packages/eslint-plugin/src/lib/configs/recommended.json rename to packages/eslint-plugin/src/configs/recommended.json diff --git a/packages/eslint-plugin/src/index.ts b/packages/eslint-plugin/src/index.ts index fd00335d7251..098478ef9f1c 100644 --- a/packages/eslint-plugin/src/index.ts +++ b/packages/eslint-plugin/src/index.ts @@ -11,15 +11,16 @@ import requireIndex from 'requireindex'; import path from 'path'; +import recommended from './configs/recommended.json'; + //------------------------------------------------------------------------------ // Plugin Definition //------------------------------------------------------------------------------ // import all rules in lib/rules -export default { - rules: requireIndex(path.join(__dirname, 'rules')), +export = { + rules: requireIndex(path.join(__dirname, 'lib/rules')), configs: { - // eslint-disable-next-line node/no-unpublished-require - recommended: require('./configs/recommended') + recommended } }; diff --git a/packages/eslint-plugin/src/lib/rules/adjacent-overload-signatures.ts b/packages/eslint-plugin/src/lib/rules/adjacent-overload-signatures.ts index 62f49a780618..d8185be31d9d 100644 --- a/packages/eslint-plugin/src/lib/rules/adjacent-overload-signatures.ts +++ b/packages/eslint-plugin/src/lib/rules/adjacent-overload-signatures.ts @@ -10,7 +10,7 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'suggestion', docs: { @@ -119,3 +119,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/array-type.ts b/packages/eslint-plugin/src/lib/rules/array-type.ts index f77413a4e0df..be0eb0cb6c89 100644 --- a/packages/eslint-plugin/src/lib/rules/array-type.ts +++ b/packages/eslint-plugin/src/lib/rules/array-type.ts @@ -77,7 +77,7 @@ function typeNeedsParentheses(node): boolean { const defaultOptions = ['array']; -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'suggestion', docs: { @@ -241,3 +241,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/ban-types.ts b/packages/eslint-plugin/src/lib/rules/ban-types.ts index a36f9f181311..893512aac303 100644 --- a/packages/eslint-plugin/src/lib/rules/ban-types.ts +++ b/packages/eslint-plugin/src/lib/rules/ban-types.ts @@ -10,10 +10,10 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -type TypeErrorConfig = { +interface TypeErrorConfig { message: string; fixWith?: string; -}; +} const defaultOptions = [ { types: { @@ -41,7 +41,7 @@ const defaultOptions = [ } ]; -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'suggestion', docs: { @@ -125,3 +125,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/camelcase.ts b/packages/eslint-plugin/src/lib/rules/camelcase.ts index fefbcd910d2f..e14eaaa2ce49 100644 --- a/packages/eslint-plugin/src/lib/rules/camelcase.ts +++ b/packages/eslint-plugin/src/lib/rules/camelcase.ts @@ -19,7 +19,7 @@ const defaultOptions = [ ]; /* eslint-disable eslint-plugin/require-meta-type */ -module.exports = { +const rule: Rule.RuleModule = { meta: Object.assign({}, baseRule.meta, { docs: { description: 'Enforce camelCase naming convention', @@ -117,3 +117,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/class-name-casing.ts b/packages/eslint-plugin/src/lib/rules/class-name-casing.ts index 42bdf01f392b..2316f1390f17 100644 --- a/packages/eslint-plugin/src/lib/rules/class-name-casing.ts +++ b/packages/eslint-plugin/src/lib/rules/class-name-casing.ts @@ -11,7 +11,7 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'suggestion', docs: { @@ -92,3 +92,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/explicit-function-return-type.ts b/packages/eslint-plugin/src/lib/rules/explicit-function-return-type.ts index 964012858e25..558100b98842 100644 --- a/packages/eslint-plugin/src/lib/rules/explicit-function-return-type.ts +++ b/packages/eslint-plugin/src/lib/rules/explicit-function-return-type.ts @@ -16,7 +16,7 @@ const defaultOptions = [ } ]; -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'problem', docs: { @@ -108,3 +108,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/explicit-member-accessibility.ts b/packages/eslint-plugin/src/lib/rules/explicit-member-accessibility.ts index 89543c305689..c3ceb793855a 100644 --- a/packages/eslint-plugin/src/lib/rules/explicit-member-accessibility.ts +++ b/packages/eslint-plugin/src/lib/rules/explicit-member-accessibility.ts @@ -10,7 +10,7 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'problem', docs: { @@ -77,3 +77,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/generic-type-naming.ts b/packages/eslint-plugin/src/lib/rules/generic-type-naming.ts index 72897bde345d..77cda5898c7a 100644 --- a/packages/eslint-plugin/src/lib/rules/generic-type-naming.ts +++ b/packages/eslint-plugin/src/lib/rules/generic-type-naming.ts @@ -10,7 +10,7 @@ const defaultOptions = [ '^T([A-Z0-9][a-zA-Z0-9]*){0,1}$' ]; -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'suggestion', docs: { @@ -51,3 +51,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/indent.ts b/packages/eslint-plugin/src/lib/rules/indent.ts index 92d7d4c7e53d..496cff0f36e5 100644 --- a/packages/eslint-plugin/src/lib/rules/indent.ts +++ b/packages/eslint-plugin/src/lib/rules/indent.ts @@ -3,7 +3,6 @@ * @author Patricio Trevino */ -import * as ESTree from 'estree'; import { Rule } from 'eslint'; import baseRule from 'eslint/lib/rules/indent'; import * as util from '../util'; @@ -91,7 +90,7 @@ const defaultOptions = [ } ]; -module.exports = Object.assign({}, baseRule, { +const rule: Rule.RuleModule = Object.assign({}, baseRule, { meta: { type: 'layout', docs: { @@ -400,3 +399,4 @@ module.exports = Object.assign({}, baseRule, { }); } }); +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/interface-name-prefix.ts b/packages/eslint-plugin/src/lib/rules/interface-name-prefix.ts index 165b57003e11..a6c03a675c8d 100644 --- a/packages/eslint-plugin/src/lib/rules/interface-name-prefix.ts +++ b/packages/eslint-plugin/src/lib/rules/interface-name-prefix.ts @@ -12,7 +12,7 @@ import * as util from '../util'; const defaultOptions = ['never']; -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'suggestion', docs: { @@ -73,3 +73,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/member-delimiter-style.ts b/packages/eslint-plugin/src/lib/rules/member-delimiter-style.ts index 8c3fa3c96aed..b27360f0f768 100644 --- a/packages/eslint-plugin/src/lib/rules/member-delimiter-style.ts +++ b/packages/eslint-plugin/src/lib/rules/member-delimiter-style.ts @@ -12,7 +12,7 @@ import * as util from '../util'; //------------------------------------------------------------------------------ type Delimiter = 'comma' | 'none' | 'semi'; -type BaseOptions = { +interface BaseOptions { multiline: { delimiter: Delimiter; requireLast: boolean; @@ -21,13 +21,13 @@ type BaseOptions = { delimiter: Delimiter; requireLast: boolean; }; -}; -type Options = BaseOptions & { +} +interface Options extends BaseOptions { overrides?: { typeLiteral?: BaseOptions; interface?: BaseOptions; }; -}; +} const defaultOptions: Options[] = [ { multiline: { @@ -65,7 +65,7 @@ const definition = { additionalProperties: false }; -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'suggestion', docs: { @@ -235,3 +235,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/member-naming.ts b/packages/eslint-plugin/src/lib/rules/member-naming.ts index 5d707aa59888..9d615a678f96 100644 --- a/packages/eslint-plugin/src/lib/rules/member-naming.ts +++ b/packages/eslint-plugin/src/lib/rules/member-naming.ts @@ -10,16 +10,16 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -type Options = { +interface Options { private?: T; protected?: T; public?: T; -}; +} type Modifiers = keyof Options; const defaultOptions: Options[] = [{}]; -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'suggestion', docs: { @@ -102,3 +102,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/member-ordering.ts b/packages/eslint-plugin/src/lib/rules/member-ordering.ts index ab1d289fff50..d8871c69186a 100644 --- a/packages/eslint-plugin/src/lib/rules/member-ordering.ts +++ b/packages/eslint-plugin/src/lib/rules/member-ordering.ts @@ -32,13 +32,13 @@ const schemaOptions = ['field', 'method', 'constructor'].reduce( ); type OrderConfig = string[] | 'never'; -type Options = { +interface Options { default: OrderConfig; classes?: OrderConfig; classExpressions?: OrderConfig; interfaces?: OrderConfig; typeLiterals?: OrderConfig; -}; +} const defaultOptions: Options[] = [ { @@ -82,7 +82,7 @@ const defaultOptions: Options[] = [ } ]; -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'suggestion', docs: { @@ -390,3 +390,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/no-angle-bracket-type-assertion.ts b/packages/eslint-plugin/src/lib/rules/no-angle-bracket-type-assertion.ts index 2f44527ef3a8..04d28d341e84 100644 --- a/packages/eslint-plugin/src/lib/rules/no-angle-bracket-type-assertion.ts +++ b/packages/eslint-plugin/src/lib/rules/no-angle-bracket-type-assertion.ts @@ -10,7 +10,7 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'problem', docs: { @@ -44,3 +44,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/no-array-constructor.ts b/packages/eslint-plugin/src/lib/rules/no-array-constructor.ts index 5bc068164cf2..9b0e2ded4a07 100644 --- a/packages/eslint-plugin/src/lib/rules/no-array-constructor.ts +++ b/packages/eslint-plugin/src/lib/rules/no-array-constructor.ts @@ -11,7 +11,7 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'suggestion', docs: { @@ -63,3 +63,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/no-empty-interface.ts b/packages/eslint-plugin/src/lib/rules/no-empty-interface.ts index 41c79605d315..44af962bfe8f 100644 --- a/packages/eslint-plugin/src/lib/rules/no-empty-interface.ts +++ b/packages/eslint-plugin/src/lib/rules/no-empty-interface.ts @@ -10,7 +10,7 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'suggestion', docs: { @@ -51,3 +51,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/no-explicit-any.ts b/packages/eslint-plugin/src/lib/rules/no-explicit-any.ts index c0b4e7f7097a..19fd06b22f13 100644 --- a/packages/eslint-plugin/src/lib/rules/no-explicit-any.ts +++ b/packages/eslint-plugin/src/lib/rules/no-explicit-any.ts @@ -11,7 +11,7 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'suggestion', docs: { @@ -35,3 +35,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/no-extraneous-class.ts b/packages/eslint-plugin/src/lib/rules/no-extraneous-class.ts index 52dbcaff3953..53ad3932dbb1 100644 --- a/packages/eslint-plugin/src/lib/rules/no-extraneous-class.ts +++ b/packages/eslint-plugin/src/lib/rules/no-extraneous-class.ts @@ -18,7 +18,7 @@ const defaultOptions = [ } ]; -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'suggestion', docs: { @@ -110,3 +110,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/no-inferrable-types.ts b/packages/eslint-plugin/src/lib/rules/no-inferrable-types.ts index 28be699b5bb1..1224c8167e02 100644 --- a/packages/eslint-plugin/src/lib/rules/no-inferrable-types.ts +++ b/packages/eslint-plugin/src/lib/rules/no-inferrable-types.ts @@ -17,7 +17,7 @@ const defaultOptions = [ } ]; -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'suggestion', docs: { @@ -184,3 +184,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/no-misused-new.ts b/packages/eslint-plugin/src/lib/rules/no-misused-new.ts index d8d9c7d96d82..51eb76d6cd1a 100644 --- a/packages/eslint-plugin/src/lib/rules/no-misused-new.ts +++ b/packages/eslint-plugin/src/lib/rules/no-misused-new.ts @@ -10,7 +10,7 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'problem', docs: { @@ -96,3 +96,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/no-namespace.ts b/packages/eslint-plugin/src/lib/rules/no-namespace.ts index 117f9ff58159..411375cf7d06 100644 --- a/packages/eslint-plugin/src/lib/rules/no-namespace.ts +++ b/packages/eslint-plugin/src/lib/rules/no-namespace.ts @@ -17,7 +17,7 @@ const defaultOptions = [ } ]; -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'suggestion', docs: { @@ -76,3 +76,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/no-non-null-assertion.ts b/packages/eslint-plugin/src/lib/rules/no-non-null-assertion.ts index 4fc2a86f3e87..8c0dccd2c7ab 100644 --- a/packages/eslint-plugin/src/lib/rules/no-non-null-assertion.ts +++ b/packages/eslint-plugin/src/lib/rules/no-non-null-assertion.ts @@ -10,7 +10,7 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'problem', docs: { @@ -38,3 +38,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/no-object-literal-type-assertion.ts b/packages/eslint-plugin/src/lib/rules/no-object-literal-type-assertion.ts index 336a526b8283..97b47f5ae910 100644 --- a/packages/eslint-plugin/src/lib/rules/no-object-literal-type-assertion.ts +++ b/packages/eslint-plugin/src/lib/rules/no-object-literal-type-assertion.ts @@ -10,7 +10,7 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'problem', docs: { @@ -64,3 +64,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/no-parameter-properties.ts b/packages/eslint-plugin/src/lib/rules/no-parameter-properties.ts index e2b216f9040c..3c8e8325f3d9 100644 --- a/packages/eslint-plugin/src/lib/rules/no-parameter-properties.ts +++ b/packages/eslint-plugin/src/lib/rules/no-parameter-properties.ts @@ -16,7 +16,7 @@ const defaultOptions = [ } ]; -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'problem', docs: { @@ -95,3 +95,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/no-this-alias.ts b/packages/eslint-plugin/src/lib/rules/no-this-alias.ts index 703e32abf385..ab4cf1d7dc77 100644 --- a/packages/eslint-plugin/src/lib/rules/no-this-alias.ts +++ b/packages/eslint-plugin/src/lib/rules/no-this-alias.ts @@ -17,7 +17,7 @@ const defaultOptions = [ } ]; -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'suggestion', docs: { @@ -75,3 +75,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/no-triple-slash-reference.ts b/packages/eslint-plugin/src/lib/rules/no-triple-slash-reference.ts index a2d43ab0cfb0..9409005f0456 100644 --- a/packages/eslint-plugin/src/lib/rules/no-triple-slash-reference.ts +++ b/packages/eslint-plugin/src/lib/rules/no-triple-slash-reference.ts @@ -10,7 +10,7 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'suggestion', docs: { @@ -62,3 +62,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/no-type-alias.ts b/packages/eslint-plugin/src/lib/rules/no-type-alias.ts index 556c91e7f8f1..26e11c4b058d 100644 --- a/packages/eslint-plugin/src/lib/rules/no-type-alias.ts +++ b/packages/eslint-plugin/src/lib/rules/no-type-alias.ts @@ -19,7 +19,7 @@ const defaultOptions = [ } ]; -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'suggestion', docs: { @@ -296,3 +296,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/no-unused-vars.ts b/packages/eslint-plugin/src/lib/rules/no-unused-vars.ts index 139eee1e8f71..9fb2d5189e62 100644 --- a/packages/eslint-plugin/src/lib/rules/no-unused-vars.ts +++ b/packages/eslint-plugin/src/lib/rules/no-unused-vars.ts @@ -12,7 +12,7 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -module.exports = Object.assign({}, baseRule, { +const rule: Rule.RuleModule = Object.assign({}, baseRule, { meta: { type: 'problem', docs: { @@ -95,3 +95,4 @@ module.exports = Object.assign({}, baseRule, { }); } }); +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/no-use-before-define.ts b/packages/eslint-plugin/src/lib/rules/no-use-before-define.ts index 8f35008ef2ad..975c58c9fe07 100644 --- a/packages/eslint-plugin/src/lib/rules/no-use-before-define.ts +++ b/packages/eslint-plugin/src/lib/rules/no-use-before-define.ts @@ -16,12 +16,12 @@ import * as util from '../util'; const SENTINEL_TYPE = /^(?:(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|CatchClause|ImportDeclaration|ExportNamedDeclaration)$/; const FOR_IN_OF_TYPE = /^For(?:In|Of)Statement$/; -type Options = { +interface Options { functions?: boolean; classes?: boolean; variables?: boolean; typedefs?: boolean; -}; +} /** * Parses a given value as options. @@ -195,7 +195,7 @@ const defaultOptions = [ } ]; -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'problem', docs: { @@ -297,3 +297,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/no-var-requires.ts b/packages/eslint-plugin/src/lib/rules/no-var-requires.ts index cd9155b37bde..305a1545ed68 100644 --- a/packages/eslint-plugin/src/lib/rules/no-var-requires.ts +++ b/packages/eslint-plugin/src/lib/rules/no-var-requires.ts @@ -10,7 +10,7 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'problem', docs: { @@ -43,3 +43,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/prefer-interface.ts b/packages/eslint-plugin/src/lib/rules/prefer-interface.ts index e3431f081ef4..9fb45a0671d5 100644 --- a/packages/eslint-plugin/src/lib/rules/prefer-interface.ts +++ b/packages/eslint-plugin/src/lib/rules/prefer-interface.ts @@ -10,7 +10,7 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'suggestion', docs: { @@ -67,3 +67,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/prefer-namespace-keyword.ts b/packages/eslint-plugin/src/lib/rules/prefer-namespace-keyword.ts index 7eb5ef92f2c5..9864e215b93c 100644 --- a/packages/eslint-plugin/src/lib/rules/prefer-namespace-keyword.ts +++ b/packages/eslint-plugin/src/lib/rules/prefer-namespace-keyword.ts @@ -11,7 +11,7 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'suggestion', docs: { @@ -59,3 +59,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/rules/type-annotation-spacing.ts b/packages/eslint-plugin/src/lib/rules/type-annotation-spacing.ts index f4f2b068ceef..4819e63b26af 100644 --- a/packages/eslint-plugin/src/lib/rules/type-annotation-spacing.ts +++ b/packages/eslint-plugin/src/lib/rules/type-annotation-spacing.ts @@ -26,7 +26,7 @@ const defaultOptions = [ {} ]; -module.exports = { +const rule: Rule.RuleModule = { meta: { type: 'layout', docs: { @@ -187,3 +187,4 @@ module.exports = { }; } }; +export = rule; diff --git a/packages/eslint-plugin/src/lib/util.ts b/packages/eslint-plugin/src/lib/util.ts index a0d5721ba8e8..c52d943eb478 100644 --- a/packages/eslint-plugin/src/lib/util.ts +++ b/packages/eslint-plugin/src/lib/util.ts @@ -38,7 +38,7 @@ export function isDefinitionFile(fileName: string) { * @param obj an object * @returns `true` if obj is an object */ -function isObjectNotArray(obj: T | Array): obj is T { +function isObjectNotArray(obj: T | any[]): obj is T { return typeof obj === 'object' && !Array.isArray(obj); } diff --git a/packages/eslint-plugin/tsconfig.json b/packages/eslint-plugin/tsconfig.json index d8a23e63b590..b2fcd92b4b8b 100644 --- a/packages/eslint-plugin/tsconfig.json +++ b/packages/eslint-plugin/tsconfig.json @@ -2,7 +2,8 @@ "extends": "../../tsconfig.json", "compilerOptions": { "declaration": false, - "outDir": "./dist" + "outDir": "./dist", + "resolveJsonModule": true }, "include": ["src", "typings"] } diff --git a/packages/typescript-estree/src/parser.ts b/packages/typescript-estree/src/parser.ts index cdf62ac7a472..8101fc762a4d 100644 --- a/packages/typescript-estree/src/parser.ts +++ b/packages/typescript-estree/src/parser.ts @@ -360,11 +360,11 @@ export function parse( return generateAST(code, options).estree; } -export type ParserServices = { +export interface ParserServices { program: ts.Program; esTreeNodeToTSNodeMap: WeakMap; tsNodeToESTreeNodeMap: WeakMap; -}; +} export function parseAndGenerateServices( code: string, options: T From 5e683325002aeb89f12fdbbca697ac5ef7803a92 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 21 Jan 2019 21:45:44 -0800 Subject: [PATCH 05/92] correct tooling paths --- packages/eslint-plugin/.npmignore | 3 +-- packages/eslint-plugin/tools/update-recommended.js | 10 +++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/eslint-plugin/.npmignore b/packages/eslint-plugin/.npmignore index 3d63d33280c4..d684bcadbd2d 100644 --- a/packages/eslint-plugin/.npmignore +++ b/packages/eslint-plugin/.npmignore @@ -1,6 +1,5 @@ **/* -!lib/**/* +!dist/**/* !docs/**/* !package.json -!parser.js !README.md diff --git a/packages/eslint-plugin/tools/update-recommended.js b/packages/eslint-plugin/tools/update-recommended.js index ce402c3933be..5579c45ab4d0 100644 --- a/packages/eslint-plugin/tools/update-recommended.js +++ b/packages/eslint-plugin/tools/update-recommended.js @@ -1,9 +1,9 @@ /* eslint-disable no-console */ 'use strict'; -const path = require('path'); -const fs = require('fs'); -const requireIndex = require('requireindex'); +import path from 'path'; +import fs from 'fs'; +import requireIndex from 'requireindex'; const bannedRecommendedRules = new Set([ 'camelcase', @@ -19,7 +19,7 @@ const MAX_RULE_NAME_LENGTH = 32 + 'typescript/'.length; */ function generate() { // replace this with Object.entries when node > 8 - const allRules = requireIndex(path.resolve(__dirname, '../lib/rules')); + const allRules = requireIndex(path.resolve(__dirname, '../src/lib/rules')); const rules = Object.keys(allRules) .filter(key => !!allRules[key].meta.docs.recommended) @@ -46,7 +46,7 @@ function generate() { return config; }, {}); - const filePath = path.resolve(__dirname, '../lib/configs/recommended.json'); + const filePath = path.resolve(__dirname, '../src/configs/recommended.json'); const recommendedConfig = { parser: '@typescript-eslint/parser', From bbc841a5649e7f030a0a45fda4a9c205716cc04e Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 21 Jan 2019 22:15:37 -0800 Subject: [PATCH 06/92] fix update-recommended script --- packages/eslint-plugin/package.json | 5 +- .../src/configs/recommended.json | 80 +++++++++---------- .../eslint-plugin/tools/update-recommended.js | 63 --------------- .../eslint-plugin/tools/update-recommended.ts | 71 ++++++++++++++++ yarn.lock | 26 +++++- 5 files changed, 138 insertions(+), 107 deletions(-) delete mode 100644 packages/eslint-plugin/tools/update-recommended.js create mode 100644 packages/eslint-plugin/tools/update-recommended.ts diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 990d1feee1e2..1757023f33d9 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -21,7 +21,7 @@ "docs": "eslint-docs", "docs:check": "eslint-docs check", "test": "jest --coverage", - "recommended:update": "node tools/update-recommended.js", + "recommended:update": "ts-node tools/update-recommended.ts", "prebuild": "npm run clean", "build": "tsc", "clean": "rimraf dist/" @@ -32,7 +32,8 @@ }, "devDependencies": { "eslint": "^5.9.0", - "eslint-docs": "^0.2.6" + "eslint-docs": "^0.2.6", + "ts-node": "^8.0.1" }, "peerDependencies": { "eslint": ">=4.13.1 < 6", diff --git a/packages/eslint-plugin/src/configs/recommended.json b/packages/eslint-plugin/src/configs/recommended.json index cd21778bfff1..4cdd013a1074 100644 --- a/packages/eslint-plugin/src/configs/recommended.json +++ b/packages/eslint-plugin/src/configs/recommended.json @@ -1,42 +1,42 @@ { - "parser": "@typescript-eslint/parser", - "parserOptions": { - "sourceType": "module" - }, - "plugins": [ - "@typescript-eslint" - ], - "rules": { - "@typescript-eslint/adjacent-overload-signatures": "error", - "@typescript-eslint/array-type": "error", - "@typescript-eslint/ban-types": "error", - "camelcase": "off", - "@typescript-eslint/camelcase": "error", - "@typescript-eslint/class-name-casing": "error", - "@typescript-eslint/explicit-function-return-type": "warn", - "@typescript-eslint/explicit-member-accessibility": "error", - "indent": "off", - "@typescript-eslint/indent": "error", - "@typescript-eslint/interface-name-prefix": "error", - "@typescript-eslint/member-delimiter-style": "error", - "@typescript-eslint/no-angle-bracket-type-assertion": "error", - "no-array-constructor": "off", - "@typescript-eslint/no-array-constructor": "error", - "@typescript-eslint/no-empty-interface": "error", - "@typescript-eslint/no-explicit-any": "warn", - "@typescript-eslint/no-inferrable-types": "error", - "@typescript-eslint/no-misused-new": "error", - "@typescript-eslint/no-namespace": "error", - "@typescript-eslint/no-non-null-assertion": "error", - "@typescript-eslint/no-object-literal-type-assertion": "error", - "@typescript-eslint/no-parameter-properties": "error", - "@typescript-eslint/no-triple-slash-reference": "error", - "no-unused-vars": "off", - "@typescript-eslint/no-unused-vars": "warn", - "@typescript-eslint/no-use-before-define": "error", - "@typescript-eslint/no-var-requires": "error", - "@typescript-eslint/prefer-interface": "error", - "@typescript-eslint/prefer-namespace-keyword": "error", - "@typescript-eslint/type-annotation-spacing": "error" - } + "parser": "@typescript-eslint/parser", + "parserOptions": { + "sourceType": "module" + }, + "plugins": [ + "@typescript-eslint" + ], + "rules": { + "@typescript-eslint/adjacent-overload-signatures": "error", + "@typescript-eslint/array-type": "error", + "@typescript-eslint/ban-types": "error", + "camelcase": "off", + "@typescript-eslint/camelcase": "error", + "@typescript-eslint/class-name-casing": "error", + "@typescript-eslint/explicit-function-return-type": "warn", + "@typescript-eslint/explicit-member-accessibility": "error", + "indent": "off", + "@typescript-eslint/indent": "error", + "@typescript-eslint/interface-name-prefix": "error", + "@typescript-eslint/member-delimiter-style": "error", + "@typescript-eslint/no-angle-bracket-type-assertion": "error", + "no-array-constructor": "off", + "@typescript-eslint/no-array-constructor": "error", + "@typescript-eslint/no-empty-interface": "error", + "@typescript-eslint/no-explicit-any": "warn", + "@typescript-eslint/no-inferrable-types": "error", + "@typescript-eslint/no-misused-new": "error", + "@typescript-eslint/no-namespace": "error", + "@typescript-eslint/no-non-null-assertion": "error", + "@typescript-eslint/no-object-literal-type-assertion": "error", + "@typescript-eslint/no-parameter-properties": "error", + "@typescript-eslint/no-triple-slash-reference": "error", + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": "warn", + "@typescript-eslint/no-use-before-define": "error", + "@typescript-eslint/no-var-requires": "error", + "@typescript-eslint/prefer-interface": "error", + "@typescript-eslint/prefer-namespace-keyword": "error", + "@typescript-eslint/type-annotation-spacing": "error" + } } diff --git a/packages/eslint-plugin/tools/update-recommended.js b/packages/eslint-plugin/tools/update-recommended.js deleted file mode 100644 index 5579c45ab4d0..000000000000 --- a/packages/eslint-plugin/tools/update-recommended.js +++ /dev/null @@ -1,63 +0,0 @@ -/* eslint-disable no-console */ -'use strict'; - -import path from 'path'; -import fs from 'fs'; -import requireIndex from 'requireindex'; - -const bannedRecommendedRules = new Set([ - 'camelcase', - 'indent', - 'no-array-constructor', - 'no-unused-vars' -]); -const MAX_RULE_NAME_LENGTH = 32 + 'typescript/'.length; - -/** - * Generate recommended configuration - * @returns {void} - */ -function generate() { - // replace this with Object.entries when node > 8 - const allRules = requireIndex(path.resolve(__dirname, '../src/lib/rules')); - - const rules = Object.keys(allRules) - .filter(key => !!allRules[key].meta.docs.recommended) - .reduce((config, key) => { - // having this here is just for output niceness (the keys will be ordered) - if (bannedRecommendedRules.has(key)) { - console.log(key.padEnd(MAX_RULE_NAME_LENGTH), '= off'); - config[key] = 'off'; - } - - const ruleName = `typescript/${key}`; - const setting = allRules[key].meta.docs.recommended; - - if (!['error', 'warn'].includes(setting)) { - console.log(`ERR! Invalid level for rule ${key}: "${setting}"`); - // Don't want to throw an error since ^ explains what happened. - // eslint-disable-next-line no-process-exit - process.exit(1); - } - - console.log(ruleName.padEnd(MAX_RULE_NAME_LENGTH), '=', setting); - config[ruleName] = setting; - - return config; - }, {}); - - const filePath = path.resolve(__dirname, '../src/configs/recommended.json'); - - const recommendedConfig = { - parser: '@typescript-eslint/parser', - parserOptions: { - sourceType: 'module' - }, - plugins: ['typescript'], - rules - }; - - fs.writeFileSync(filePath, `${JSON.stringify(recommendedConfig, null, 4)}\n`); -} - -generate(); diff --git a/packages/eslint-plugin/tools/update-recommended.ts b/packages/eslint-plugin/tools/update-recommended.ts new file mode 100644 index 000000000000..4cfa6dca4aac --- /dev/null +++ b/packages/eslint-plugin/tools/update-recommended.ts @@ -0,0 +1,71 @@ +/* eslint-disable no-console */ + +import path from 'path'; +import fs from 'fs'; +import requireIndex from 'requireindex'; + +const bannedRecommendedRules = new Set([ + 'camelcase', + 'indent', + 'no-array-constructor', + 'no-unused-vars' +]); +const MAX_RULE_NAME_LENGTH = 32 + 'typescript/'.length; + +function padEnd(str: string, length: number): string { + while (str.length < length) { + str += ' '; + } + return str; +} + +/** + * Generate recommended configuration + */ +function generate(): void { + // replace this with Object.entries when node > 8 + const allRules = requireIndex(path.resolve(__dirname, '../dist/lib/rules')); + + const rules = Object.keys(allRules) + .filter(key => !!allRules[key].meta.docs.recommended) + .reduce( + (config, key) => { + // having this here is just for output niceness (the keys will be ordered) + if (bannedRecommendedRules.has(key)) { + console.log(padEnd(key, MAX_RULE_NAME_LENGTH), '= off'); + config[key] = 'off'; + } + + const ruleName = `@typescript-eslint/${key}`; + const setting = allRules[key].meta.docs.recommended; + + if (!['error', 'warn'].includes(setting)) { + console.log(`ERR! Invalid level for rule ${key}: "${setting}"`); + // Don't want to throw an error since ^ explains what happened. + // eslint-disable-next-line no-process-exit + process.exit(1); + } + + console.log(padEnd(ruleName, MAX_RULE_NAME_LENGTH), '=', setting); + config[ruleName] = setting; + + return config; + }, + {} as Record + ); + + const filePath = path.resolve(__dirname, '../src/configs/recommended.json'); + + const recommendedConfig = { + parser: '@typescript-eslint/parser', + parserOptions: { + sourceType: 'module' + }, + plugins: ['@typescript-eslint'], + rules + }; + + fs.writeFileSync(filePath, `${JSON.stringify(recommendedConfig, null, 4)}\n`); +} + +generate(); diff --git a/yarn.lock b/yarn.lock index a80ac0413712..7a6a93243c42 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1017,6 +1017,11 @@ are-we-there-yet@~1.1.2: delegates "^1.0.0" readable-stream "^2.0.6" +arg@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.0.tgz#583c518199419e0037abb74062c37f8519e575f0" + integrity sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg== + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -2176,7 +2181,7 @@ dezalgo@^1.0.0: asap "^2.0.0" wrappy "1" -diff@^3.2.0, diff@^3.5.0: +diff@^3.1.0, diff@^3.2.0, diff@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== @@ -4654,7 +4659,7 @@ make-dir@^1.0.0: dependencies: pify "^3.0.0" -make-error@1.x: +make-error@1.x, make-error@^1.1.1: version "1.3.5" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8" integrity sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g== @@ -6859,6 +6864,18 @@ ts-jest@^23.10.4: semver "^5.5" yargs-parser "10.x" +ts-node@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.0.1.tgz#cad98e8d50f0474f0d763ca8dc4c1bf8b7554ae2" + integrity sha512-zER3Js6Iotp31ghen6nKjgX75UOipwTWX9T5fAVmHaaYAizWhOes4uAsLmDC8H51UG5tHL8gNjoa/wLFjo7wtA== + dependencies: + arg "^4.1.0" + arrify "^1.0.0" + diff "^3.1.0" + make-error "^1.1.1" + source-map-support "^0.5.6" + yn "^2.0.0" + tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" @@ -7281,3 +7298,8 @@ yargs@^12.0.1: which-module "^2.0.0" y18n "^3.2.1 || ^4.0.0" yargs-parser "^11.1.1" + +yn@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" + integrity sha1-5a2ryKz0CPY4X8dklWhMiOavaJo= From 0d3e8ffe09967fd1504ffbc842b450b53ac35f5c Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Tue, 22 Jan 2019 09:49:08 -0800 Subject: [PATCH 07/92] add missing manual module typing files --- .gitignore | 3 --- packages/eslint-plugin/typings/eslint-rules.d.ts | 12 ++++++++++++ packages/eslint-plugin/typings/eslint.d.ts | 10 ++++++++++ packages/eslint-plugin/typings/requireindex.d.ts | 9 +++++++++ 4 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 packages/eslint-plugin/typings/eslint-rules.d.ts create mode 100644 packages/eslint-plugin/typings/eslint.d.ts create mode 100644 packages/eslint-plugin/typings/requireindex.d.ts diff --git a/.gitignore b/.gitignore index 213ae9c36aa4..3f0f6536564b 100644 --- a/.gitignore +++ b/.gitignore @@ -36,9 +36,6 @@ build/Release node_modules/ jspm_packages/ -# TypeScript v1 declaration files -typings/ - # Optional npm cache directory .npm diff --git a/packages/eslint-plugin/typings/eslint-rules.d.ts b/packages/eslint-plugin/typings/eslint-rules.d.ts new file mode 100644 index 000000000000..9c7c0dbeb4b6 --- /dev/null +++ b/packages/eslint-plugin/typings/eslint-rules.d.ts @@ -0,0 +1,12 @@ +declare module 'eslint/lib/rules/*' { + import { Node } from 'estree'; + import { Rule } from 'eslint'; + + // intentionally redefined here instead of using Rule.RuleListener + // because eslint only uses the `node => void` signature + const rule: { + create(context: Rule.RuleContext): Record void>; + meta: Rule.RuleMetaData; + }; + export = rule; +} diff --git a/packages/eslint-plugin/typings/eslint.d.ts b/packages/eslint-plugin/typings/eslint.d.ts new file mode 100644 index 000000000000..980be331ab46 --- /dev/null +++ b/packages/eslint-plugin/typings/eslint.d.ts @@ -0,0 +1,10 @@ +// module augmentation is weird +import { Scope } from 'eslint'; +declare module 'eslint' { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + namespace Scope { + interface Variable { + eslintUsed: boolean; + } + } +} diff --git a/packages/eslint-plugin/typings/requireindex.d.ts b/packages/eslint-plugin/typings/requireindex.d.ts new file mode 100644 index 000000000000..7ddf009d87f9 --- /dev/null +++ b/packages/eslint-plugin/typings/requireindex.d.ts @@ -0,0 +1,9 @@ +declare module 'requireindex' { + type RequireIndex = ( + path: string, + basenames?: string[] + ) => Record; + + const fn: RequireIndex; + export = fn; +} From d4254f529750a10c63a3b0799916d684a4d01700 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Tue, 22 Jan 2019 13:29:42 -0800 Subject: [PATCH 08/92] address some review comments --- .../eslint-plugin/src/lib/rules/ban-types.ts | 15 ++++--- .../src/lib/rules/member-naming.ts | 4 +- .../src/lib/rules/member-ordering.ts | 4 +- packages/eslint-plugin/src/lib/util.ts | 4 +- .../eslint-plugin/tools/update-recommended.ts | 39 +++++++++---------- tsconfig.json | 3 -- 6 files changed, 34 insertions(+), 35 deletions(-) diff --git a/packages/eslint-plugin/src/lib/rules/ban-types.ts b/packages/eslint-plugin/src/lib/rules/ban-types.ts index 893512aac303..b218b989e995 100644 --- a/packages/eslint-plugin/src/lib/rules/ban-types.ts +++ b/packages/eslint-plugin/src/lib/rules/ban-types.ts @@ -10,11 +10,16 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -interface TypeErrorConfig { - message: string; - fixWith?: string; +interface Options { + types: Record< + string, + { + message: string; + fixWith?: string; + } + >; } -const defaultOptions = [ +const defaultOptions: Options[] = [ { types: { String: { @@ -37,7 +42,7 @@ const defaultOptions = [ message: 'Use symbol instead', fixWith: 'symbol' } - } as Record + } } ]; diff --git a/packages/eslint-plugin/src/lib/rules/member-naming.ts b/packages/eslint-plugin/src/lib/rules/member-naming.ts index 9d615a678f96..8f8134ddc08c 100644 --- a/packages/eslint-plugin/src/lib/rules/member-naming.ts +++ b/packages/eslint-plugin/src/lib/rules/member-naming.ts @@ -57,13 +57,13 @@ const rule: Rule.RuleModule = { create(context: Rule.RuleContext) { const config = util.applyDefault(defaultOptions, context.options)[0]; - const conventions = (Object.keys(config) as Modifiers[]).reduce( + const conventions = (Object.keys(config) as Modifiers[]).reduce>( (acc, accessibility) => { acc[accessibility] = new RegExp(config[accessibility]!); return acc; }, - {} as Options + {} ); //---------------------------------------------------------------------- diff --git a/packages/eslint-plugin/src/lib/rules/member-ordering.ts b/packages/eslint-plugin/src/lib/rules/member-ordering.ts index d8871c69186a..c995a12634cf 100644 --- a/packages/eslint-plugin/src/lib/rules/member-ordering.ts +++ b/packages/eslint-plugin/src/lib/rules/member-ordering.ts @@ -10,7 +10,7 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -const schemaOptions = ['field', 'method', 'constructor'].reduce( +const schemaOptions = ['field', 'method', 'constructor'].reduce( (options, type) => { options.push(type); @@ -28,7 +28,7 @@ const schemaOptions = ['field', 'method', 'constructor'].reduce( return options; }, - [] as string[] + [] ); type OrderConfig = string[] | 'never'; diff --git a/packages/eslint-plugin/src/lib/util.ts b/packages/eslint-plugin/src/lib/util.ts index c52d943eb478..559c2629ec1d 100644 --- a/packages/eslint-plugin/src/lib/util.ts +++ b/packages/eslint-plugin/src/lib/util.ts @@ -1,6 +1,7 @@ import { Rule } from 'eslint'; import { ParserServices } from '@typescript-eslint/typescript-estree'; +// note - cannot migrate this to an import statement because it will make TSC copy the package.json to the dist folder const version = require('../../package.json').version; export type ObjectLike = Record; @@ -56,7 +57,7 @@ export function deepMerge( // get the unique set of keys across both objects const keys = new Set(Object.keys(first).concat(Object.keys(second))); - return Array.from(keys).reduce( + return Array.from(keys).reduce( (acc, key) => { const firstHasKey = key in first; const secondHasKey = key in second; @@ -84,7 +85,6 @@ export function deepMerge( /** * Pure function - doesn't mutate either parameter! * Uses the default options and overrides with the options provided by the user - * @template TOptions * @param defaultOptions the defaults * @param userOptions the user opts * @returns the options with defaults diff --git a/packages/eslint-plugin/tools/update-recommended.ts b/packages/eslint-plugin/tools/update-recommended.ts index 4cfa6dca4aac..45e286dce7f5 100644 --- a/packages/eslint-plugin/tools/update-recommended.ts +++ b/packages/eslint-plugin/tools/update-recommended.ts @@ -28,31 +28,28 @@ function generate(): void { const rules = Object.keys(allRules) .filter(key => !!allRules[key].meta.docs.recommended) - .reduce( - (config, key) => { - // having this here is just for output niceness (the keys will be ordered) - if (bannedRecommendedRules.has(key)) { - console.log(padEnd(key, MAX_RULE_NAME_LENGTH), '= off'); - config[key] = 'off'; - } + .reduce>((config, key) => { + // having this here is just for output niceness (the keys will be ordered) + if (bannedRecommendedRules.has(key)) { + console.log(padEnd(key, MAX_RULE_NAME_LENGTH), '= off'); + config[key] = 'off'; + } - const ruleName = `@typescript-eslint/${key}`; - const setting = allRules[key].meta.docs.recommended; + const ruleName = `@typescript-eslint/${key}`; + const setting = allRules[key].meta.docs.recommended; - if (!['error', 'warn'].includes(setting)) { - console.log(`ERR! Invalid level for rule ${key}: "${setting}"`); - // Don't want to throw an error since ^ explains what happened. - // eslint-disable-next-line no-process-exit - process.exit(1); - } + if (!['error', 'warn'].includes(setting)) { + console.log(`ERR! Invalid level for rule ${key}: "${setting}"`); + // Don't want to throw an error since ^ explains what happened. + // eslint-disable-next-line no-process-exit + process.exit(1); + } - console.log(padEnd(ruleName, MAX_RULE_NAME_LENGTH), '=', setting); - config[ruleName] = setting; + console.log(padEnd(ruleName, MAX_RULE_NAME_LENGTH), '=', setting); + config[ruleName] = setting; - return config; - }, - {} as Record - ); + return config; + }, {}); const filePath = path.resolve(__dirname, '../src/configs/recommended.json'); diff --git a/tsconfig.json b/tsconfig.json index d11f498502fd..d6b0130a25ad 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,13 +3,10 @@ "allowSyntheticDefaultImports": true, "allowUnreachableCode": false, "allowUnusedLabels": false, - "alwaysStrict": true, "esModuleInterop": true, "module": "commonjs", "moduleResolution": "node", - "noImplicitAny": true, "noImplicitReturns": true, - "noImplicitThis": true, "noUnusedLocals": true, "noUnusedParameters": true, "pretty": true, From e44fba51ff881b642a3a96232488c3380ffabf2b Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Thu, 24 Jan 2019 10:19:59 -0800 Subject: [PATCH 09/92] convert tests to TS, move folders, fix bugs --- .vscode/launch.json | 2 +- packages/eslint-plugin/jest.config.js | 10 +- packages/eslint-plugin/src/index.ts | 2 +- .../rules/adjacent-overload-signatures.ts | 3 +- .../src/{lib => }/rules/array-type.ts | 0 .../src/{lib => }/rules/ban-types.ts | 0 .../src/{lib => }/rules/camelcase.ts | 0 .../src/{lib => }/rules/class-name-casing.ts | 0 .../rules/explicit-function-return-type.ts | 0 .../rules/explicit-member-accessibility.ts | 0 .../{lib => }/rules/generic-type-naming.ts | 0 .../src/{lib => }/rules/indent.ts | 0 .../{lib => }/rules/interface-name-prefix.ts | 0 .../{lib => }/rules/member-delimiter-style.ts | 0 .../src/{lib => }/rules/member-naming.ts | 0 .../src/{lib => }/rules/member-ordering.ts | 0 .../rules/no-angle-bracket-type-assertion.ts | 0 .../{lib => }/rules/no-array-constructor.ts | 0 .../src/{lib => }/rules/no-empty-interface.ts | 0 .../src/{lib => }/rules/no-explicit-any.ts | 0 .../{lib => }/rules/no-extraneous-class.ts | 0 .../{lib => }/rules/no-inferrable-types.ts | 0 .../src/{lib => }/rules/no-misused-new.ts | 0 .../src/{lib => }/rules/no-namespace.ts | 0 .../{lib => }/rules/no-non-null-assertion.ts | 0 .../rules/no-object-literal-type-assertion.ts | 0 .../rules/no-parameter-properties.ts | 0 .../src/{lib => }/rules/no-this-alias.ts | 0 .../rules/no-triple-slash-reference.ts | 0 .../src/{lib => }/rules/no-type-alias.ts | 0 .../src/{lib => }/rules/no-unused-vars.ts | 0 .../{lib => }/rules/no-use-before-define.ts | 0 .../src/{lib => }/rules/no-var-requires.ts | 0 .../src/{lib => }/rules/prefer-interface.ts | 0 .../rules/prefer-namespace-keyword.ts | 0 .../{lib => }/rules/restrict-plus-operands.ts | 0 .../rules/type-annotation-spacing.ts | 0 packages/eslint-plugin/src/{lib => }/util.ts | 2 +- .../no-dupe-args.ts} | 4 +- .../no-implicit-globals.ts} | 4 +- .../no-redeclare.ts} | 4 +- .../no-restricted-globals.ts} | 4 +- .../no-shadow.ts} | 4 +- .../no-undef.js => eslint-rules/no-undef.ts} | 4 +- .../no-unused-vars.ts} | 4 +- .../no-use-before-define.ts} | 4 +- .../strict.js => eslint-rules/strict.ts} | 4 +- .../adjacent-overload-signatures.ts} | 220 +--------- .../array-type.js => rules/array-type.ts} | 14 +- .../rules/ban-types.js => rules/ban-types.ts} | 5 +- .../rules/camelcase.js => rules/camelcase.ts} | 7 +- .../class-name-casing.ts} | 5 +- .../explicit-function-return-type.ts} | 5 +- .../explicit-member-accessibility.ts} | 5 +- .../generic-type-naming.ts} | 5 +- .../{lib/rules/indent.js => rules/indent.ts} | 14 +- .../interface-name-prefix.ts} | 5 +- .../member-delimiter-style.ts} | 5 +- .../member-naming.ts} | 5 +- .../member-ordering.ts} | 5 +- .../no-angle-bracket-type-assertion.ts} | 19 +- .../no-array-constructor.ts} | 5 +- .../no-empty-interface.ts} | 5 +- .../no-explicit-any.ts} | 5 +- .../no-extraneous-class.ts} | 21 +- .../no-inferrable-types.ts} | 5 +- .../no-misused-new.ts} | 5 +- .../no-namespace.js => rules/no-namespace.ts} | 49 ++- .../no-non-null-assertion.ts} | 5 +- .../no-object-literal-type-assertion.ts} | 5 +- .../no-parameter-properties.ts} | 5 +- .../no-this-alias.ts} | 11 +- .../no-triple-slash-reference.ts} | 5 +- .../no-type-alias.ts} | 401 +++++++++--------- .../no-unused-vars.ts} | 5 +- .../no-use-before-define.ts} | 6 +- .../no-var-requires.ts} | 5 +- .../prefer-interface.ts} | 5 +- .../prefer-namespace-keyword.ts} | 13 +- .../restrict-plus-operands.ts} | 5 +- .../type-annotation-spacing.ts} | 13 +- .../tests/{lib/util.js => util.ts} | 9 +- packages/eslint-plugin/typings/eslint.d.ts | 11 +- 83 files changed, 369 insertions(+), 604 deletions(-) rename packages/eslint-plugin/src/{lib => }/rules/adjacent-overload-signatures.ts (98%) rename packages/eslint-plugin/src/{lib => }/rules/array-type.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/ban-types.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/camelcase.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/class-name-casing.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/explicit-function-return-type.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/explicit-member-accessibility.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/generic-type-naming.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/indent.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/interface-name-prefix.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/member-delimiter-style.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/member-naming.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/member-ordering.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/no-angle-bracket-type-assertion.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/no-array-constructor.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/no-empty-interface.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/no-explicit-any.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/no-extraneous-class.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/no-inferrable-types.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/no-misused-new.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/no-namespace.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/no-non-null-assertion.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/no-object-literal-type-assertion.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/no-parameter-properties.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/no-this-alias.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/no-triple-slash-reference.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/no-type-alias.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/no-unused-vars.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/no-use-before-define.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/no-var-requires.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/prefer-interface.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/prefer-namespace-keyword.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/restrict-plus-operands.ts (100%) rename packages/eslint-plugin/src/{lib => }/rules/type-annotation-spacing.ts (100%) rename packages/eslint-plugin/src/{lib => }/util.ts (98%) rename packages/eslint-plugin/tests/{lib/eslint-rules/no-dupe-args.js => eslint-rules/no-dupe-args.ts} (85%) rename packages/eslint-plugin/tests/{lib/eslint-rules/no-implicit-globals.js => eslint-rules/no-implicit-globals.ts} (84%) rename packages/eslint-plugin/tests/{lib/eslint-rules/no-redeclare.js => eslint-rules/no-redeclare.ts} (87%) rename packages/eslint-plugin/tests/{lib/eslint-rules/no-restricted-globals.js => eslint-rules/no-restricted-globals.ts} (86%) rename packages/eslint-plugin/tests/{lib/eslint-rules/no-shadow.js => eslint-rules/no-shadow.ts} (87%) rename packages/eslint-plugin/tests/{lib/eslint-rules/no-undef.js => eslint-rules/no-undef.ts} (94%) rename packages/eslint-plugin/tests/{lib/eslint-rules/no-unused-vars.js => eslint-rules/no-unused-vars.ts} (86%) rename packages/eslint-plugin/tests/{lib/eslint-rules/no-use-before-define.js => eslint-rules/no-use-before-define.ts} (87%) rename packages/eslint-plugin/tests/{lib/eslint-rules/strict.js => eslint-rules/strict.ts} (90%) rename packages/eslint-plugin/tests/{lib/rules/adjacent-overload-signatures.js => rules/adjacent-overload-signatures.ts} (71%) rename packages/eslint-plugin/tests/{lib/rules/array-type.js => rules/array-type.ts} (98%) rename packages/eslint-plugin/tests/{lib/rules/ban-types.js => rules/ban-types.ts} (97%) rename packages/eslint-plugin/tests/{lib/rules/camelcase.js => rules/camelcase.ts} (96%) rename packages/eslint-plugin/tests/{lib/rules/class-name-casing.js => rules/class-name-casing.ts} (95%) rename packages/eslint-plugin/tests/{lib/rules/explicit-function-return-type.js => rules/explicit-function-return-type.ts} (96%) rename packages/eslint-plugin/tests/{lib/rules/explicit-member-accessibility.js => rules/explicit-member-accessibility.ts} (94%) rename packages/eslint-plugin/tests/{lib/rules/generic-type-naming.js => rules/generic-type-naming.ts} (97%) rename packages/eslint-plugin/tests/{lib/rules/indent.js => rules/indent.ts} (98%) rename packages/eslint-plugin/tests/{lib/rules/interface-name-prefix.js => rules/interface-name-prefix.ts} (95%) rename packages/eslint-plugin/tests/{lib/rules/member-delimiter-style.js => rules/member-delimiter-style.ts} (99%) rename packages/eslint-plugin/tests/{lib/rules/member-naming.js => rules/member-naming.ts} (97%) rename packages/eslint-plugin/tests/{lib/rules/member-ordering.js => rules/member-ordering.ts} (99%) rename packages/eslint-plugin/tests/{lib/rules/no-angle-bracket-type-assertion.js => rules/no-angle-bracket-type-assertion.ts} (91%) rename packages/eslint-plugin/tests/{lib/rules/no-array-constructor.js => rules/no-array-constructor.ts} (94%) rename packages/eslint-plugin/tests/{lib/rules/no-empty-interface.js => rules/no-empty-interface.ts} (92%) rename packages/eslint-plugin/tests/{lib/rules/no-explicit-any.js => rules/no-explicit-any.ts} (99%) rename packages/eslint-plugin/tests/{lib/rules/no-extraneous-class.js => rules/no-extraneous-class.ts} (92%) rename packages/eslint-plugin/tests/{lib/rules/no-inferrable-types.js => rules/no-inferrable-types.ts} (97%) rename packages/eslint-plugin/tests/{lib/rules/no-misused-new.js => rules/no-misused-new.ts} (95%) rename packages/eslint-plugin/tests/{lib/rules/no-namespace.js => rules/no-namespace.ts} (87%) rename packages/eslint-plugin/tests/{lib/rules/no-non-null-assertion.js => rules/no-non-null-assertion.ts} (87%) rename packages/eslint-plugin/tests/{lib/rules/no-object-literal-type-assertion.js => rules/no-object-literal-type-assertion.ts} (94%) rename packages/eslint-plugin/tests/{lib/rules/no-parameter-properties.js => rules/no-parameter-properties.ts} (98%) rename packages/eslint-plugin/tests/{lib/rules/no-this-alias.js => rules/no-this-alias.ts} (94%) rename packages/eslint-plugin/tests/{lib/rules/no-triple-slash-reference.js => rules/no-triple-slash-reference.ts} (91%) rename packages/eslint-plugin/tests/{lib/rules/no-type-alias.js => rules/no-type-alias.ts} (93%) rename packages/eslint-plugin/tests/{lib/rules/no-unused-vars.js => rules/no-unused-vars.ts} (99%) rename packages/eslint-plugin/tests/{lib/rules/no-use-before-define.js => rules/no-use-before-define.ts} (99%) rename packages/eslint-plugin/tests/{lib/rules/no-var-requires.js => rules/no-var-requires.ts} (91%) rename packages/eslint-plugin/tests/{lib/rules/prefer-interface.js => rules/prefer-interface.ts} (93%) rename packages/eslint-plugin/tests/{lib/rules/prefer-namespace-keyword.js => rules/prefer-namespace-keyword.ts} (90%) rename packages/eslint-plugin/tests/{lib/rules/restrict-plus-operands.js => rules/restrict-plus-operands.ts} (97%) rename packages/eslint-plugin/tests/{lib/rules/type-annotation-spacing.js => rules/type-annotation-spacing.ts} (99%) rename packages/eslint-plugin/tests/{lib/util.js => util.ts} (96%) diff --git a/.vscode/launch.json b/.vscode/launch.json index 18bf27ada556..0fe37133fceb 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -12,7 +12,7 @@ "program": "${workspaceFolder}/node_modules/jest/bin/jest.js", "args": [ "--colors", - "${workspaceFolder}/packages/eslint-plugin/tests/lib/rules/${fileBasename}" + "${workspaceFolder}/packages/eslint-plugin/tests/rules/${fileBasename}" ], "console": "integratedTerminal", "internalConsoleOptions": "neverOpen" diff --git a/packages/eslint-plugin/jest.config.js b/packages/eslint-plugin/jest.config.js index 8c1bc93c7f0e..66423febf197 100644 --- a/packages/eslint-plugin/jest.config.js +++ b/packages/eslint-plugin/jest.config.js @@ -1,13 +1,19 @@ 'use strict'; module.exports = { + globals: { + 'ts-jest': { + // TODO - re-enable type checking when the build is working + isolatedModules: true, + }, + }, testEnvironment: 'node', transform: { '^.+\\.tsx?$': 'ts-jest' }, - testRegex: './tests/lib/.+\\.js$', + testRegex: './tests/.+\\.ts$', collectCoverage: false, - collectCoverageFrom: ['lib/**/*.{js,jsx,ts,tsx}'], + collectCoverageFrom: ['src/**/*.{js,jsx,ts,tsx}'], moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], coverageReporters: ['text-summary', 'lcov'] }; diff --git a/packages/eslint-plugin/src/index.ts b/packages/eslint-plugin/src/index.ts index 098478ef9f1c..db3ad4e94002 100644 --- a/packages/eslint-plugin/src/index.ts +++ b/packages/eslint-plugin/src/index.ts @@ -19,7 +19,7 @@ import recommended from './configs/recommended.json'; // import all rules in lib/rules export = { - rules: requireIndex(path.join(__dirname, 'lib/rules')), + rules: requireIndex(path.join(__dirname, 'rules')), configs: { recommended } diff --git a/packages/eslint-plugin/src/lib/rules/adjacent-overload-signatures.ts b/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts similarity index 98% rename from packages/eslint-plugin/src/lib/rules/adjacent-overload-signatures.ts rename to packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts index d8185be31d9d..032fa8cf6dac 100644 --- a/packages/eslint-plugin/src/lib/rules/adjacent-overload-signatures.ts +++ b/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts @@ -80,12 +80,13 @@ const rule: Rule.RuleModule = { const members = node.body || node.members; if (members) { - let lastName: string; + let lastName: string | null; const seen: string[] = []; members.forEach(member => { const name = getMemberName(member); if (name === null) { + lastName = null; return; } diff --git a/packages/eslint-plugin/src/lib/rules/array-type.ts b/packages/eslint-plugin/src/rules/array-type.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/array-type.ts rename to packages/eslint-plugin/src/rules/array-type.ts diff --git a/packages/eslint-plugin/src/lib/rules/ban-types.ts b/packages/eslint-plugin/src/rules/ban-types.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/ban-types.ts rename to packages/eslint-plugin/src/rules/ban-types.ts diff --git a/packages/eslint-plugin/src/lib/rules/camelcase.ts b/packages/eslint-plugin/src/rules/camelcase.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/camelcase.ts rename to packages/eslint-plugin/src/rules/camelcase.ts diff --git a/packages/eslint-plugin/src/lib/rules/class-name-casing.ts b/packages/eslint-plugin/src/rules/class-name-casing.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/class-name-casing.ts rename to packages/eslint-plugin/src/rules/class-name-casing.ts diff --git a/packages/eslint-plugin/src/lib/rules/explicit-function-return-type.ts b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/explicit-function-return-type.ts rename to packages/eslint-plugin/src/rules/explicit-function-return-type.ts diff --git a/packages/eslint-plugin/src/lib/rules/explicit-member-accessibility.ts b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/explicit-member-accessibility.ts rename to packages/eslint-plugin/src/rules/explicit-member-accessibility.ts diff --git a/packages/eslint-plugin/src/lib/rules/generic-type-naming.ts b/packages/eslint-plugin/src/rules/generic-type-naming.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/generic-type-naming.ts rename to packages/eslint-plugin/src/rules/generic-type-naming.ts diff --git a/packages/eslint-plugin/src/lib/rules/indent.ts b/packages/eslint-plugin/src/rules/indent.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/indent.ts rename to packages/eslint-plugin/src/rules/indent.ts diff --git a/packages/eslint-plugin/src/lib/rules/interface-name-prefix.ts b/packages/eslint-plugin/src/rules/interface-name-prefix.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/interface-name-prefix.ts rename to packages/eslint-plugin/src/rules/interface-name-prefix.ts diff --git a/packages/eslint-plugin/src/lib/rules/member-delimiter-style.ts b/packages/eslint-plugin/src/rules/member-delimiter-style.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/member-delimiter-style.ts rename to packages/eslint-plugin/src/rules/member-delimiter-style.ts diff --git a/packages/eslint-plugin/src/lib/rules/member-naming.ts b/packages/eslint-plugin/src/rules/member-naming.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/member-naming.ts rename to packages/eslint-plugin/src/rules/member-naming.ts diff --git a/packages/eslint-plugin/src/lib/rules/member-ordering.ts b/packages/eslint-plugin/src/rules/member-ordering.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/member-ordering.ts rename to packages/eslint-plugin/src/rules/member-ordering.ts diff --git a/packages/eslint-plugin/src/lib/rules/no-angle-bracket-type-assertion.ts b/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/no-angle-bracket-type-assertion.ts rename to packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts diff --git a/packages/eslint-plugin/src/lib/rules/no-array-constructor.ts b/packages/eslint-plugin/src/rules/no-array-constructor.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/no-array-constructor.ts rename to packages/eslint-plugin/src/rules/no-array-constructor.ts diff --git a/packages/eslint-plugin/src/lib/rules/no-empty-interface.ts b/packages/eslint-plugin/src/rules/no-empty-interface.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/no-empty-interface.ts rename to packages/eslint-plugin/src/rules/no-empty-interface.ts diff --git a/packages/eslint-plugin/src/lib/rules/no-explicit-any.ts b/packages/eslint-plugin/src/rules/no-explicit-any.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/no-explicit-any.ts rename to packages/eslint-plugin/src/rules/no-explicit-any.ts diff --git a/packages/eslint-plugin/src/lib/rules/no-extraneous-class.ts b/packages/eslint-plugin/src/rules/no-extraneous-class.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/no-extraneous-class.ts rename to packages/eslint-plugin/src/rules/no-extraneous-class.ts diff --git a/packages/eslint-plugin/src/lib/rules/no-inferrable-types.ts b/packages/eslint-plugin/src/rules/no-inferrable-types.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/no-inferrable-types.ts rename to packages/eslint-plugin/src/rules/no-inferrable-types.ts diff --git a/packages/eslint-plugin/src/lib/rules/no-misused-new.ts b/packages/eslint-plugin/src/rules/no-misused-new.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/no-misused-new.ts rename to packages/eslint-plugin/src/rules/no-misused-new.ts diff --git a/packages/eslint-plugin/src/lib/rules/no-namespace.ts b/packages/eslint-plugin/src/rules/no-namespace.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/no-namespace.ts rename to packages/eslint-plugin/src/rules/no-namespace.ts diff --git a/packages/eslint-plugin/src/lib/rules/no-non-null-assertion.ts b/packages/eslint-plugin/src/rules/no-non-null-assertion.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/no-non-null-assertion.ts rename to packages/eslint-plugin/src/rules/no-non-null-assertion.ts diff --git a/packages/eslint-plugin/src/lib/rules/no-object-literal-type-assertion.ts b/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/no-object-literal-type-assertion.ts rename to packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts diff --git a/packages/eslint-plugin/src/lib/rules/no-parameter-properties.ts b/packages/eslint-plugin/src/rules/no-parameter-properties.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/no-parameter-properties.ts rename to packages/eslint-plugin/src/rules/no-parameter-properties.ts diff --git a/packages/eslint-plugin/src/lib/rules/no-this-alias.ts b/packages/eslint-plugin/src/rules/no-this-alias.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/no-this-alias.ts rename to packages/eslint-plugin/src/rules/no-this-alias.ts diff --git a/packages/eslint-plugin/src/lib/rules/no-triple-slash-reference.ts b/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/no-triple-slash-reference.ts rename to packages/eslint-plugin/src/rules/no-triple-slash-reference.ts diff --git a/packages/eslint-plugin/src/lib/rules/no-type-alias.ts b/packages/eslint-plugin/src/rules/no-type-alias.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/no-type-alias.ts rename to packages/eslint-plugin/src/rules/no-type-alias.ts diff --git a/packages/eslint-plugin/src/lib/rules/no-unused-vars.ts b/packages/eslint-plugin/src/rules/no-unused-vars.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/no-unused-vars.ts rename to packages/eslint-plugin/src/rules/no-unused-vars.ts diff --git a/packages/eslint-plugin/src/lib/rules/no-use-before-define.ts b/packages/eslint-plugin/src/rules/no-use-before-define.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/no-use-before-define.ts rename to packages/eslint-plugin/src/rules/no-use-before-define.ts diff --git a/packages/eslint-plugin/src/lib/rules/no-var-requires.ts b/packages/eslint-plugin/src/rules/no-var-requires.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/no-var-requires.ts rename to packages/eslint-plugin/src/rules/no-var-requires.ts diff --git a/packages/eslint-plugin/src/lib/rules/prefer-interface.ts b/packages/eslint-plugin/src/rules/prefer-interface.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/prefer-interface.ts rename to packages/eslint-plugin/src/rules/prefer-interface.ts diff --git a/packages/eslint-plugin/src/lib/rules/prefer-namespace-keyword.ts b/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/prefer-namespace-keyword.ts rename to packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts diff --git a/packages/eslint-plugin/src/lib/rules/restrict-plus-operands.ts b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/restrict-plus-operands.ts rename to packages/eslint-plugin/src/rules/restrict-plus-operands.ts diff --git a/packages/eslint-plugin/src/lib/rules/type-annotation-spacing.ts b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts similarity index 100% rename from packages/eslint-plugin/src/lib/rules/type-annotation-spacing.ts rename to packages/eslint-plugin/src/rules/type-annotation-spacing.ts diff --git a/packages/eslint-plugin/src/lib/util.ts b/packages/eslint-plugin/src/util.ts similarity index 98% rename from packages/eslint-plugin/src/lib/util.ts rename to packages/eslint-plugin/src/util.ts index 7ad4ce7deb69..ad14422dee23 100644 --- a/packages/eslint-plugin/src/lib/util.ts +++ b/packages/eslint-plugin/src/util.ts @@ -2,7 +2,7 @@ import { Rule } from 'eslint'; import { ParserServices } from '@typescript-eslint/typescript-estree'; // note - cannot migrate this to an import statement because it will make TSC copy the package.json to the dist folder -const version = require('../../package.json').version; +const version = require('../package.json').version; export type ObjectLike = Record; diff --git a/packages/eslint-plugin/tests/lib/eslint-rules/no-dupe-args.js b/packages/eslint-plugin/tests/eslint-rules/no-dupe-args.ts similarity index 85% rename from packages/eslint-plugin/tests/lib/eslint-rules/no-dupe-args.js rename to packages/eslint-plugin/tests/eslint-rules/no-dupe-args.ts index 65d2c88314e0..ed44993a0d6f 100644 --- a/packages/eslint-plugin/tests/lib/eslint-rules/no-dupe-args.js +++ b/packages/eslint-plugin/tests/eslint-rules/no-dupe-args.ts @@ -4,8 +4,8 @@ // Requirements //------------------------------------------------------------------------------ -const rule = require('eslint/lib/rules/no-dupe-args'), - RuleTester = require('eslint').RuleTester; +import rule from 'eslint/lib/rules/no-dupe-args'; +import { RuleTester } from 'eslint'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/lib/eslint-rules/no-implicit-globals.js b/packages/eslint-plugin/tests/eslint-rules/no-implicit-globals.ts similarity index 84% rename from packages/eslint-plugin/tests/lib/eslint-rules/no-implicit-globals.js rename to packages/eslint-plugin/tests/eslint-rules/no-implicit-globals.ts index 654c3374ca8b..bf43b2f283c3 100644 --- a/packages/eslint-plugin/tests/lib/eslint-rules/no-implicit-globals.js +++ b/packages/eslint-plugin/tests/eslint-rules/no-implicit-globals.ts @@ -4,8 +4,8 @@ // Requirements //------------------------------------------------------------------------------ -const rule = require('eslint/lib/rules/no-implicit-globals'), - RuleTester = require('eslint').RuleTester; +import rule from 'eslint/lib/rules/no-implicit-globals'; +import { RuleTester } from 'eslint'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/lib/eslint-rules/no-redeclare.js b/packages/eslint-plugin/tests/eslint-rules/no-redeclare.ts similarity index 87% rename from packages/eslint-plugin/tests/lib/eslint-rules/no-redeclare.js rename to packages/eslint-plugin/tests/eslint-rules/no-redeclare.ts index 05b3efa9bb41..090345c5e5fc 100644 --- a/packages/eslint-plugin/tests/lib/eslint-rules/no-redeclare.js +++ b/packages/eslint-plugin/tests/eslint-rules/no-redeclare.ts @@ -4,8 +4,8 @@ // Requirements //------------------------------------------------------------------------------ -const rule = require('eslint/lib/rules/no-redeclare'), - RuleTester = require('eslint').RuleTester; +import rule from 'eslint/lib/rules/no-redeclare'; +import { RuleTester } from 'eslint'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/lib/eslint-rules/no-restricted-globals.js b/packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.ts similarity index 86% rename from packages/eslint-plugin/tests/lib/eslint-rules/no-restricted-globals.js rename to packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.ts index a88cb359a5df..a6ebf38a26db 100644 --- a/packages/eslint-plugin/tests/lib/eslint-rules/no-restricted-globals.js +++ b/packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.ts @@ -4,8 +4,8 @@ // Requirements //------------------------------------------------------------------------------ -const rule = require('eslint/lib/rules/no-restricted-globals'), - RuleTester = require('eslint').RuleTester; +import rule from 'eslint/lib/rules/no-restricted-globals'; +import { RuleTester } from 'eslint'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/lib/eslint-rules/no-shadow.js b/packages/eslint-plugin/tests/eslint-rules/no-shadow.ts similarity index 87% rename from packages/eslint-plugin/tests/lib/eslint-rules/no-shadow.js rename to packages/eslint-plugin/tests/eslint-rules/no-shadow.ts index 68901aed4310..ff5da6cd4b31 100644 --- a/packages/eslint-plugin/tests/lib/eslint-rules/no-shadow.js +++ b/packages/eslint-plugin/tests/eslint-rules/no-shadow.ts @@ -4,8 +4,8 @@ // Requirements //------------------------------------------------------------------------------ -const rule = require('eslint/lib/rules/no-shadow'), - RuleTester = require('eslint').RuleTester; +import rule from 'eslint/lib/rules/no-shadow'; +import { RuleTester } from 'eslint'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/lib/eslint-rules/no-undef.js b/packages/eslint-plugin/tests/eslint-rules/no-undef.ts similarity index 94% rename from packages/eslint-plugin/tests/lib/eslint-rules/no-undef.js rename to packages/eslint-plugin/tests/eslint-rules/no-undef.ts index 53a148eee9da..fb53559fa901 100644 --- a/packages/eslint-plugin/tests/lib/eslint-rules/no-undef.js +++ b/packages/eslint-plugin/tests/eslint-rules/no-undef.ts @@ -8,8 +8,8 @@ // Requirements //------------------------------------------------------------------------------ -const rule = require('eslint/lib/rules/no-undef'), - RuleTester = require('eslint').RuleTester; +import rule from 'eslint/lib/rules/no-undef'; +import { RuleTester } from 'eslint'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/lib/eslint-rules/no-unused-vars.js b/packages/eslint-plugin/tests/eslint-rules/no-unused-vars.ts similarity index 86% rename from packages/eslint-plugin/tests/lib/eslint-rules/no-unused-vars.js rename to packages/eslint-plugin/tests/eslint-rules/no-unused-vars.ts index 1e80a0dd6502..c2de51ab7065 100644 --- a/packages/eslint-plugin/tests/lib/eslint-rules/no-unused-vars.js +++ b/packages/eslint-plugin/tests/eslint-rules/no-unused-vars.ts @@ -4,8 +4,8 @@ // Requirements //------------------------------------------------------------------------------ -const rule = require('eslint/lib/rules/no-unused-vars'), - RuleTester = require('eslint').RuleTester; +import rule from 'eslint/lib/rules/no-unused-vars'; +import { RuleTester } from 'eslint'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/lib/eslint-rules/no-use-before-define.js b/packages/eslint-plugin/tests/eslint-rules/no-use-before-define.ts similarity index 87% rename from packages/eslint-plugin/tests/lib/eslint-rules/no-use-before-define.js rename to packages/eslint-plugin/tests/eslint-rules/no-use-before-define.ts index 4a16ea4c8a03..aa2c7a26bb3a 100644 --- a/packages/eslint-plugin/tests/lib/eslint-rules/no-use-before-define.js +++ b/packages/eslint-plugin/tests/eslint-rules/no-use-before-define.ts @@ -4,8 +4,8 @@ // Requirements //------------------------------------------------------------------------------ -const rule = require('eslint/lib/rules/no-use-before-define'), - RuleTester = require('eslint').RuleTester; +import rule from 'eslint/lib/rules/no-use-before-define'; +import { RuleTester } from 'eslint'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/lib/eslint-rules/strict.js b/packages/eslint-plugin/tests/eslint-rules/strict.ts similarity index 90% rename from packages/eslint-plugin/tests/lib/eslint-rules/strict.js rename to packages/eslint-plugin/tests/eslint-rules/strict.ts index 173849371d9f..46eda6f948ed 100644 --- a/packages/eslint-plugin/tests/lib/eslint-rules/strict.js +++ b/packages/eslint-plugin/tests/eslint-rules/strict.ts @@ -4,8 +4,8 @@ // Requirements //------------------------------------------------------------------------------ -const rule = require('eslint/lib/rules/strict'), - RuleTester = require('eslint').RuleTester; +import rule from 'eslint/lib/rules/strict'; +import { RuleTester } from 'eslint'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/lib/rules/adjacent-overload-signatures.js b/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.ts similarity index 71% rename from packages/eslint-plugin/tests/lib/rules/adjacent-overload-signatures.js rename to packages/eslint-plugin/tests/rules/adjacent-overload-signatures.ts index 161ffd4035e6..79ad64cb5ae4 100644 --- a/packages/eslint-plugin/tests/lib/rules/adjacent-overload-signatures.js +++ b/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.ts @@ -2,14 +2,13 @@ * @fileoverview Enforces member overloads to be consecutive. * @author Patricio Trevino */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/adjacent-overload-signatures'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/adjacent-overload-signatures'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests @@ -20,225 +19,12 @@ const ruleTester = new RuleTester({ }); ruleTester.run('adjacent-overload-signatures', rule, { - valid: [ - { - code: ` -function error(a: string); -function error(b: number); -function error(ab: string|number){ } -export { error }; - `, - parserOptions: { sourceType: 'module' } - }, - { - code: ` -import { connect } from 'react-redux'; -export interface ErrorMessageModel { message: string; } -function mapStateToProps() { } -function mapDispatchToProps() { } -export default connect(mapStateToProps, mapDispatchToProps)(ErrorMessage); - `, - parserOptions: { sourceType: 'module' } - }, - ` -export const foo = "a", bar = "b"; -export interface Foo {} -export class Foo {} - `, - ` -export interface Foo {} -export const foo = "a", bar = "b"; -export class Foo {} - `, - ` -const foo = "a", bar = "b"; -interface Foo {} -class Foo {} - `, - ` -interface Foo {} -const foo = "a", bar = "b"; -class Foo {} - `, - ` -export class Foo {} -export class Bar {} - -export type FooBar = Foo | Bar; - `, - ` -export interface Foo {} -export class Foo {} -export class Bar {} - -export type FooBar = Foo | Bar; - `, - ` -export function foo(s: string); -export function foo(n: number); -export function foo(sn: string | number) {} -export function bar(): void {} -export function baz(): void {} - `, - ` -function foo(s: string); -function foo(n: number); -function foo(sn: string | number) {} -function bar(): void {} -function baz(): void {} - `, - ` -declare function foo(s: string); -declare function foo(n: number); -declare function foo(sn: string | number); -declare function bar(): void; -declare function baz(): void; - `, - ` -declare module "Foo" { - export function foo(s: string): void; - export function foo(n: number): void; - export function foo(sn: string | number): void; - export function bar(): void; - export function baz(): void; -} - `, - ` -declare namespace Foo { - export function foo(s: string): void; - export function foo(n: number): void; - export function foo(sn: string | number): void; - export function bar(): void; - export function baz(): void; -} - `, - ` -type Foo = { - foo(s: string): void; - foo(n: number): void; - foo(sn: string | number): void; - bar(): void; - baz(): void; -} - `, - ` -type Foo = { - foo(s: string): void; - ["foo"](n: number): void; - foo(sn: string | number): void; - bar(): void; - baz(): void; -} - `, - ` -interface Foo { - (s: string): void; - (n: number): void; - (sn: string | number): void; - foo(n: number): void; - bar(): void; - baz(): void; -} - `, - ` -interface Foo { - foo(s: string): void; - foo(n: number): void; - foo(sn: string | number): void; - bar(): void; - baz(): void; -} - `, - ` -interface Foo { - foo(s: string): void; - ["foo"](n: number): void; - foo(sn: string | number): void; - bar(): void; - baz(): void; -} - `, - ` -interface Foo { - foo(): void; - bar: { - baz(s: string): void; - baz(n: number): void; - baz(sn: string | number): void; - } -} - `, - ` -interface Foo { - new(s: string); - new(n: number); - new(sn: string | number); - foo(): void; -} - `, - ` -class Foo { - constructor(s: string); - constructor(n: number); - constructor(sn: string | number) {} - bar(): void {} - baz(): void {} -} - `, - ` -class Foo { - foo(s: string): void; - foo(n: number): void; - foo(sn: string | number): void {} - bar(): void {} - baz(): void {} -} - `, - ` -class Foo { - foo(s: string): void; - ["foo"](n: number): void; - foo(sn: string | number): void {} - bar(): void {} - baz(): void {} -} - `, - ` -class Foo { - name: string; - foo(s: string): void; - foo(n: number): void; - foo(sn: string | number): void {} - bar(): void {} - baz(): void {} -} - `, - // examples from https://github.com/nzakas/eslint-plugin-typescript/issues/138 - 'export default function(foo : T) {}', - 'export default function named(foo : T) {}' - ], + valid: [], invalid: [ { code: ` export function foo(s: string); export function foo(n: number); -export function bar(): void {} -export function baz(): void {} -export function foo(sn: string | number) {} - `, - errors: [ - { - messageId: 'adjacentSignature', - data: { name: 'foo' }, - line: 6, - column: 1 - } - ] - }, - { - code: ` -export function foo(s: string); -export function foo(n: number); export type bar = number; export type baz = number | string; export function foo(sn: string | number) {} diff --git a/packages/eslint-plugin/tests/lib/rules/array-type.js b/packages/eslint-plugin/tests/rules/array-type.ts similarity index 98% rename from packages/eslint-plugin/tests/lib/rules/array-type.js rename to packages/eslint-plugin/tests/rules/array-type.ts index e39796f90c0d..64f4ad1aed4e 100644 --- a/packages/eslint-plugin/tests/lib/rules/array-type.js +++ b/packages/eslint-plugin/tests/rules/array-type.ts @@ -3,21 +3,20 @@ * @author Mackie Underdown * @author Armano */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/array-type'), - eslint = require('eslint'), - assert = require('assert'); +import rule from '../../src/rules/array-type'; +import { RuleTester, Linter } from 'eslint'; +import assert from 'assert'; //------------------------------------------------------------------------------ // Tests //------------------------------------------------------------------------------ -const ruleTester = new eslint.RuleTester({ +const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); @@ -782,9 +781,8 @@ let yyyy: Arr>>> = [[[["2"]]]];`, // https://github.com/eslint/eslint/issues/11187 describe('array-type (nested)', () => { it('should fix correctly', () => { - // eslint-disable-next-line require-jsdoc - function testOutput(option, code, output) { - const linter = new eslint.Linter(); + function testOutput(option: string, code: string, output: string): void { + const linter = new Linter(); linter.defineRule('array-type', Object.assign({}, rule)); const result = linter.verifyAndFix( diff --git a/packages/eslint-plugin/tests/lib/rules/ban-types.js b/packages/eslint-plugin/tests/rules/ban-types.ts similarity index 97% rename from packages/eslint-plugin/tests/lib/rules/ban-types.js rename to packages/eslint-plugin/tests/rules/ban-types.ts index 520640cc2063..3655e9feb10d 100644 --- a/packages/eslint-plugin/tests/lib/rules/ban-types.js +++ b/packages/eslint-plugin/tests/rules/ban-types.ts @@ -2,14 +2,13 @@ * @fileoverview Enforces that types will not to be used * @author Armano */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/ban-types'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/ban-types'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/lib/rules/camelcase.js b/packages/eslint-plugin/tests/rules/camelcase.ts similarity index 96% rename from packages/eslint-plugin/tests/lib/rules/camelcase.js rename to packages/eslint-plugin/tests/rules/camelcase.ts index 05efff9af562..3a227a1198b6 100644 --- a/packages/eslint-plugin/tests/lib/rules/camelcase.js +++ b/packages/eslint-plugin/tests/rules/camelcase.ts @@ -4,14 +4,13 @@ * @author Shahar Or * @author Patricio Trevino */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const ruleCamelcase = require('../../../lib/rules/camelcase'); -const RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/camelcase'; +import { RuleTester } from 'eslint'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' @@ -21,7 +20,7 @@ const ruleTester = new RuleTester({ // Tests //------------------------------------------------------------------------------ -ruleTester.run('camelcase', ruleCamelcase, { +ruleTester.run('camelcase', rule, { valid: [ { code: 'interface Foo { b_ar: number }', diff --git a/packages/eslint-plugin/tests/lib/rules/class-name-casing.js b/packages/eslint-plugin/tests/rules/class-name-casing.ts similarity index 95% rename from packages/eslint-plugin/tests/lib/rules/class-name-casing.js rename to packages/eslint-plugin/tests/rules/class-name-casing.ts index 59c2217ceadf..baa768cd7261 100644 --- a/packages/eslint-plugin/tests/lib/rules/class-name-casing.js +++ b/packages/eslint-plugin/tests/rules/class-name-casing.ts @@ -3,14 +3,13 @@ * @author Jed Fox * @author Armano */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/class-name-casing'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/class-name-casing'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/lib/rules/explicit-function-return-type.js b/packages/eslint-plugin/tests/rules/explicit-function-return-type.ts similarity index 96% rename from packages/eslint-plugin/tests/lib/rules/explicit-function-return-type.js rename to packages/eslint-plugin/tests/rules/explicit-function-return-type.ts index e5454b6ccc78..f8343bb1400b 100644 --- a/packages/eslint-plugin/tests/lib/rules/explicit-function-return-type.js +++ b/packages/eslint-plugin/tests/rules/explicit-function-return-type.ts @@ -2,14 +2,13 @@ * @fileoverview Enforces explicit return type for functions * @author Scott O'Hara */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/explicit-function-return-type'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/explicit-function-return-type'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/lib/rules/explicit-member-accessibility.js b/packages/eslint-plugin/tests/rules/explicit-member-accessibility.ts similarity index 94% rename from packages/eslint-plugin/tests/lib/rules/explicit-member-accessibility.js rename to packages/eslint-plugin/tests/rules/explicit-member-accessibility.ts index 0ec5f048e1fd..eb3ee827fe61 100644 --- a/packages/eslint-plugin/tests/lib/rules/explicit-member-accessibility.js +++ b/packages/eslint-plugin/tests/rules/explicit-member-accessibility.ts @@ -2,14 +2,13 @@ * @fileoverview Enforces explicit accessibility modifiers for class members * @author Danny Fritz */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/explicit-member-accessibility'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/explicit-member-accessibility'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/lib/rules/generic-type-naming.js b/packages/eslint-plugin/tests/rules/generic-type-naming.ts similarity index 97% rename from packages/eslint-plugin/tests/lib/rules/generic-type-naming.js rename to packages/eslint-plugin/tests/rules/generic-type-naming.ts index 98b0532ec6c8..152ff9e99f12 100644 --- a/packages/eslint-plugin/tests/lib/rules/generic-type-naming.js +++ b/packages/eslint-plugin/tests/rules/generic-type-naming.ts @@ -1,14 +1,13 @@ /** * @fileoverview Enforces naming of generic type variables. */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/generic-type-naming'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/generic-type-naming'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/lib/rules/indent.js b/packages/eslint-plugin/tests/rules/indent.ts similarity index 98% rename from packages/eslint-plugin/tests/lib/rules/indent.js rename to packages/eslint-plugin/tests/rules/indent.ts index c4e069e31f5c..714d8e5bf7c7 100644 --- a/packages/eslint-plugin/tests/lib/rules/indent.js +++ b/packages/eslint-plugin/tests/rules/indent.ts @@ -8,15 +8,13 @@ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/indent'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/indent'; +import { RuleTester, RuleTesterRunTests } from 'eslint'; /** * Marks a test case as a plain javascript case which should be indented the same - * @param {string} example the code - * @returns {string} marked code */ -function nonTsTestCase(example) { +function nonTsTestCase(example: TemplateStringsArray): string { return [`// Non-TS Test Case`, example].join('\n'); } @@ -613,7 +611,7 @@ type Foo = string | { ` ] } -].reduce( +].reduce( (acc, testCase) => { const indent = ' '; @@ -635,7 +633,7 @@ type Foo = string | { output: code, errors: code .split('\n') - .map((line, lineNum) => { + .map((line, lineNum) => { const indentCount = line.split(indent).length - 1; const spaceCount = indentCount * indent.length; @@ -649,7 +647,7 @@ type Foo = string | { column: 1 }; }) - .filter(error => error !== null) + .filter((error): error is RuleTester.TestCaseError => error !== null) }); }); diff --git a/packages/eslint-plugin/tests/lib/rules/interface-name-prefix.js b/packages/eslint-plugin/tests/rules/interface-name-prefix.ts similarity index 95% rename from packages/eslint-plugin/tests/lib/rules/interface-name-prefix.js rename to packages/eslint-plugin/tests/rules/interface-name-prefix.ts index 6243d5a6d11a..4cf3734661e6 100644 --- a/packages/eslint-plugin/tests/lib/rules/interface-name-prefix.js +++ b/packages/eslint-plugin/tests/rules/interface-name-prefix.ts @@ -2,14 +2,13 @@ * @fileoverview Enforces interface names are prefixed with "I" * @author Danny Fritz */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/interface-name-prefix'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/interface-name-prefix'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/lib/rules/member-delimiter-style.js b/packages/eslint-plugin/tests/rules/member-delimiter-style.ts similarity index 99% rename from packages/eslint-plugin/tests/lib/rules/member-delimiter-style.js rename to packages/eslint-plugin/tests/rules/member-delimiter-style.ts index 288269243af9..07b7c442d81d 100644 --- a/packages/eslint-plugin/tests/lib/rules/member-delimiter-style.js +++ b/packages/eslint-plugin/tests/rules/member-delimiter-style.ts @@ -3,14 +3,13 @@ * @author Patricio Trevino * @author Brad Zacher */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/member-delimiter-style'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/member-delimiter-style'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/lib/rules/member-naming.js b/packages/eslint-plugin/tests/rules/member-naming.ts similarity index 97% rename from packages/eslint-plugin/tests/lib/rules/member-naming.js rename to packages/eslint-plugin/tests/rules/member-naming.ts index c3e0d8a69209..0752f3e4f8b2 100644 --- a/packages/eslint-plugin/tests/lib/rules/member-naming.js +++ b/packages/eslint-plugin/tests/rules/member-naming.ts @@ -2,14 +2,13 @@ * @fileoverview Enforces naming conventions for class members by visibility. * @author Ian MacLeod */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/member-naming'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/member-naming'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/lib/rules/member-ordering.js b/packages/eslint-plugin/tests/rules/member-ordering.ts similarity index 99% rename from packages/eslint-plugin/tests/lib/rules/member-ordering.js rename to packages/eslint-plugin/tests/rules/member-ordering.ts index b74bcce32006..d2c1ef3e0218 100644 --- a/packages/eslint-plugin/tests/lib/rules/member-ordering.js +++ b/packages/eslint-plugin/tests/rules/member-ordering.ts @@ -2,14 +2,13 @@ * @fileoverview Enforces a standard member declaration order. * @author Patricio Trevino */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/member-ordering'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/member-ordering'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/lib/rules/no-angle-bracket-type-assertion.js b/packages/eslint-plugin/tests/rules/no-angle-bracket-type-assertion.ts similarity index 91% rename from packages/eslint-plugin/tests/lib/rules/no-angle-bracket-type-assertion.js rename to packages/eslint-plugin/tests/rules/no-angle-bracket-type-assertion.ts index f4aa7b362740..111120078bd8 100644 --- a/packages/eslint-plugin/tests/lib/rules/no-angle-bracket-type-assertion.js +++ b/packages/eslint-plugin/tests/rules/no-angle-bracket-type-assertion.ts @@ -2,14 +2,13 @@ * @fileoverview Requires the use of as Type for type assertions instead of * @author Patricio Trevino */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/no-angle-bracket-type-assertion'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/no-angle-bracket-type-assertion'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests @@ -75,13 +74,13 @@ const bar = new Generic(); { message: "Prefer 'as Foo' instead of '' when doing type assertions.", - row: 8, + line: 9, column: 13 }, { message: "Prefer 'as Foo' instead of '' when doing type assertions.", - row: 9, + line: 10, column: 13 } ] @@ -92,7 +91,7 @@ const bar = new Generic(); { message: "Prefer 'as number' instead of '' when doing type assertions.", - row: 1, + line: 1, column: 20 } ] @@ -106,7 +105,7 @@ const b : number = a; { message: "Prefer 'as number' instead of '' when doing type assertions.", - row: 3, + line: 3, column: 20 } ] @@ -117,7 +116,7 @@ const b : number = a; { message: "Prefer 'as Array' instead of '>' when doing type assertions.", - row: 1, + line: 1, column: 27 } ] @@ -133,7 +132,7 @@ const a : A = b; errors: [ { message: "Prefer 'as A' instead of '' when doing type assertions.", - row: 6, + line: 6, column: 15 } ] @@ -153,7 +152,7 @@ const a: A = b; errors: [ { message: "Prefer 'as A' instead of '' when doing type assertions.", - row: 9, + line: 10, column: 14 } ] diff --git a/packages/eslint-plugin/tests/lib/rules/no-array-constructor.js b/packages/eslint-plugin/tests/rules/no-array-constructor.ts similarity index 94% rename from packages/eslint-plugin/tests/lib/rules/no-array-constructor.js rename to packages/eslint-plugin/tests/rules/no-array-constructor.ts index 90a551722538..4e21e4000329 100644 --- a/packages/eslint-plugin/tests/lib/rules/no-array-constructor.js +++ b/packages/eslint-plugin/tests/rules/no-array-constructor.ts @@ -3,14 +3,13 @@ * @author Jed Fox * @author Matt DuVall */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/no-array-constructor'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/no-array-constructor'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/lib/rules/no-empty-interface.js b/packages/eslint-plugin/tests/rules/no-empty-interface.ts similarity index 92% rename from packages/eslint-plugin/tests/lib/rules/no-empty-interface.js rename to packages/eslint-plugin/tests/rules/no-empty-interface.ts index a16d875a366c..ef7563a6147d 100644 --- a/packages/eslint-plugin/tests/lib/rules/no-empty-interface.js +++ b/packages/eslint-plugin/tests/rules/no-empty-interface.ts @@ -2,14 +2,13 @@ * @fileoverview Disallows the declaration of empty interfaces. * @author Patricio Trevino */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/no-empty-interface'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/no-empty-interface'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/lib/rules/no-explicit-any.js b/packages/eslint-plugin/tests/rules/no-explicit-any.ts similarity index 99% rename from packages/eslint-plugin/tests/lib/rules/no-explicit-any.js rename to packages/eslint-plugin/tests/rules/no-explicit-any.ts index 2f6e09350055..10ee49ae69df 100644 --- a/packages/eslint-plugin/tests/lib/rules/no-explicit-any.js +++ b/packages/eslint-plugin/tests/rules/no-explicit-any.ts @@ -2,14 +2,13 @@ * @fileoverview Enforces the any type is not used * @author Danny Fritz */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/no-explicit-any'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/no-explicit-any'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/lib/rules/no-extraneous-class.js b/packages/eslint-plugin/tests/rules/no-extraneous-class.ts similarity index 92% rename from packages/eslint-plugin/tests/lib/rules/no-extraneous-class.js rename to packages/eslint-plugin/tests/rules/no-extraneous-class.ts index 4243677a8679..059a18c791a1 100644 --- a/packages/eslint-plugin/tests/lib/rules/no-extraneous-class.js +++ b/packages/eslint-plugin/tests/rules/no-extraneous-class.ts @@ -3,14 +3,13 @@ * Some tests adapted from https://github.com/palantir/tslint/tree/c7fc99b5/test/rules/no-unnecessary-class * @author Jed Fox */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/no-extraneous-class'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/no-extraneous-class'; +import { RuleTester } from 'eslint'; const empty = { messageId: 'empty', type: 'Identifier' }; const onlyStatic = { messageId: 'onlyStatic', type: 'Identifier' }; @@ -31,7 +30,7 @@ class Foo { public prop = 1; constructor() {} } -`.trim(), +`, ` export class CClass extends BaseClass { public static helper(): void {} @@ -40,14 +39,14 @@ export class CClass extends BaseClass { } constructor() {} } -`.trim(), +`, ` class Foo { constructor( public bar: string ) {} } -`.trim(), +`, { code: 'class Foo {}', options: [{ allowEmpty: true }] @@ -57,7 +56,7 @@ class Foo { class Foo { constructor() {} } -`.trim(), +`, options: [{ allowConstructorOnly: true }] }, { @@ -68,7 +67,7 @@ export class Bar { return true; } } -`.trim(), +`, options: [{ allowStaticOnly: true }] } ], @@ -94,7 +93,7 @@ export class Bar { return true; } } -`.trim(), +`, errors: [onlyStatic, onlyStatic] }, { @@ -102,7 +101,7 @@ export class Bar { class Foo { constructor() {} } -`.trim(), +`, errors: [onlyConstructor] }, { @@ -118,7 +117,7 @@ export class AClass { } } -`.trim(), +`, errors: [onlyStatic, empty] } ] diff --git a/packages/eslint-plugin/tests/lib/rules/no-inferrable-types.js b/packages/eslint-plugin/tests/rules/no-inferrable-types.ts similarity index 97% rename from packages/eslint-plugin/tests/lib/rules/no-inferrable-types.js rename to packages/eslint-plugin/tests/rules/no-inferrable-types.ts index 955647e27f31..874bf1238ec1 100644 --- a/packages/eslint-plugin/tests/lib/rules/no-inferrable-types.js +++ b/packages/eslint-plugin/tests/rules/no-inferrable-types.ts @@ -2,14 +2,13 @@ * @fileoverview Disallows explicit type declarations for inferrable types * @author James Garbutt */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/no-inferrable-types'); -const RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/no-inferrable-types'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/lib/rules/no-misused-new.js b/packages/eslint-plugin/tests/rules/no-misused-new.ts similarity index 95% rename from packages/eslint-plugin/tests/lib/rules/no-misused-new.js rename to packages/eslint-plugin/tests/rules/no-misused-new.ts index f770f509872a..905c74c37c6c 100644 --- a/packages/eslint-plugin/tests/lib/rules/no-misused-new.js +++ b/packages/eslint-plugin/tests/rules/no-misused-new.ts @@ -2,14 +2,13 @@ * @fileoverview Enforce valid definition of `new` and `constructor`. * @author Armano */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/no-misused-new'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/no-misused-new'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/lib/rules/no-namespace.js b/packages/eslint-plugin/tests/rules/no-namespace.ts similarity index 87% rename from packages/eslint-plugin/tests/lib/rules/no-namespace.js rename to packages/eslint-plugin/tests/rules/no-namespace.ts index cadabf185d06..75047aff510a 100644 --- a/packages/eslint-plugin/tests/lib/rules/no-namespace.js +++ b/packages/eslint-plugin/tests/rules/no-namespace.ts @@ -2,14 +2,13 @@ * @fileoverview Disallows the use of custom TypeScript modules and namespaces. * @author Patricio Trevino */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/no-namespace'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/no-namespace'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests @@ -48,7 +47,7 @@ ruleTester.run('no-namespace', rule, { errors: [ { messageId: 'moduleSyntaxIsPreferred', - row: 1, + line: 1, column: 1 } ] @@ -58,7 +57,7 @@ ruleTester.run('no-namespace', rule, { errors: [ { messageId: 'moduleSyntaxIsPreferred', - row: 1, + line: 1, column: 1 } ] @@ -69,7 +68,7 @@ ruleTester.run('no-namespace', rule, { errors: [ { messageId: 'moduleSyntaxIsPreferred', - row: 1, + line: 1, column: 1 } ] @@ -80,7 +79,7 @@ ruleTester.run('no-namespace', rule, { errors: [ { messageId: 'moduleSyntaxIsPreferred', - row: 1, + line: 1, column: 1 } ] @@ -90,7 +89,7 @@ ruleTester.run('no-namespace', rule, { errors: [ { messageId: 'moduleSyntaxIsPreferred', - row: 1, + line: 1, column: 1 } ] @@ -100,7 +99,7 @@ ruleTester.run('no-namespace', rule, { errors: [ { messageId: 'moduleSyntaxIsPreferred', - row: 1, + line: 1, column: 1 } ] @@ -111,7 +110,7 @@ ruleTester.run('no-namespace', rule, { errors: [ { messageId: 'moduleSyntaxIsPreferred', - row: 1, + line: 1, column: 1 } ] @@ -122,7 +121,7 @@ ruleTester.run('no-namespace', rule, { errors: [ { messageId: 'moduleSyntaxIsPreferred', - row: 1, + line: 1, column: 1 } ] @@ -134,7 +133,7 @@ ruleTester.run('no-namespace', rule, { errors: [ { messageId: 'moduleSyntaxIsPreferred', - row: 1, + line: 1, column: 1 } ] @@ -146,7 +145,7 @@ ruleTester.run('no-namespace', rule, { errors: [ { messageId: 'moduleSyntaxIsPreferred', - row: 1, + line: 1, column: 1 } ] @@ -158,7 +157,7 @@ ruleTester.run('no-namespace', rule, { errors: [ { messageId: 'moduleSyntaxIsPreferred', - row: 1, + line: 1, column: 1 } ] @@ -170,7 +169,7 @@ ruleTester.run('no-namespace', rule, { errors: [ { messageId: 'moduleSyntaxIsPreferred', - row: 1, + line: 1, column: 1 } ] @@ -181,29 +180,29 @@ ruleTester.run('no-namespace', rule, { errors: [ { messageId: 'moduleSyntaxIsPreferred', - row: 1, + line: 1, column: 1 } ] }, { code: ` - namespace Foo.Bar { - namespace Baz.Bas { - interface X {} - } - } +namespace Foo.Bar { + namespace Baz.Bas { + interface X {} + } +} `, errors: [ { messageId: 'moduleSyntaxIsPreferred', - row: 1, - column: 17 + line: 2, + column: 1 }, { messageId: 'moduleSyntaxIsPreferred', - row: 2, - column: 21 + line: 3, + column: 3 } ] } diff --git a/packages/eslint-plugin/tests/lib/rules/no-non-null-assertion.js b/packages/eslint-plugin/tests/rules/no-non-null-assertion.ts similarity index 87% rename from packages/eslint-plugin/tests/lib/rules/no-non-null-assertion.js rename to packages/eslint-plugin/tests/rules/no-non-null-assertion.ts index 81b79c6972dd..511d222405d0 100644 --- a/packages/eslint-plugin/tests/lib/rules/no-non-null-assertion.js +++ b/packages/eslint-plugin/tests/rules/no-non-null-assertion.ts @@ -2,14 +2,13 @@ * @fileoverview Disallows non-null assertions using the `!` postfix operator. * @author Macklin Underdown */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/no-non-null-assertion'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/no-non-null-assertion'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/lib/rules/no-object-literal-type-assertion.js b/packages/eslint-plugin/tests/rules/no-object-literal-type-assertion.ts similarity index 94% rename from packages/eslint-plugin/tests/lib/rules/no-object-literal-type-assertion.js rename to packages/eslint-plugin/tests/rules/no-object-literal-type-assertion.ts index aa19b09e8601..c5d5a6d8f6f7 100644 --- a/packages/eslint-plugin/tests/lib/rules/no-object-literal-type-assertion.js +++ b/packages/eslint-plugin/tests/rules/no-object-literal-type-assertion.ts @@ -2,14 +2,13 @@ * @fileoverview Forbids an object literal to appear in a type assertion expression * @author Armano */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/no-object-literal-type-assertion'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/no-object-literal-type-assertion'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/lib/rules/no-parameter-properties.js b/packages/eslint-plugin/tests/rules/no-parameter-properties.ts similarity index 98% rename from packages/eslint-plugin/tests/lib/rules/no-parameter-properties.js rename to packages/eslint-plugin/tests/rules/no-parameter-properties.ts index 80129de18cc6..457cda8a4c89 100644 --- a/packages/eslint-plugin/tests/lib/rules/no-parameter-properties.js +++ b/packages/eslint-plugin/tests/rules/no-parameter-properties.ts @@ -2,14 +2,13 @@ * @fileoverview Disallows parameter properties in class constructors. * @author Patricio Trevino */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/no-parameter-properties'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/no-parameter-properties'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/lib/rules/no-this-alias.js b/packages/eslint-plugin/tests/rules/no-this-alias.ts similarity index 94% rename from packages/eslint-plugin/tests/lib/rules/no-this-alias.js rename to packages/eslint-plugin/tests/rules/no-this-alias.ts index e2f76005da4d..0a665700f38c 100644 --- a/packages/eslint-plugin/tests/lib/rules/no-this-alias.js +++ b/packages/eslint-plugin/tests/rules/no-this-alias.ts @@ -3,14 +3,13 @@ * Some tests taken from TSLint: https://github.com/palantir/tslint/tree/c7fc99b5/test/rules/no-this-assignment * @author Jed Fox */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/no-this-alias'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/no-this-alias'; +import { RuleTester } from 'eslint'; const idError = { messageId: 'thisAssignment', type: 'Identifier' }; const destructureError = { @@ -40,7 +39,7 @@ const { length } = this; const { length, toString } = this; const [foo] = this; const [foo, bar] = this; -`.trim(), +`, options: [ { allowDestructuring: true @@ -91,7 +90,7 @@ function testFunction() { const testLambda = () => { const inLambda = this; }; -`.trim(), +`, errors: [idError, idError, idError] }, { @@ -114,7 +113,7 @@ class TestClass { const [foo, bar] = this; } } -`.trim(), +`, errors: [ idError, idError, diff --git a/packages/eslint-plugin/tests/lib/rules/no-triple-slash-reference.js b/packages/eslint-plugin/tests/rules/no-triple-slash-reference.ts similarity index 91% rename from packages/eslint-plugin/tests/lib/rules/no-triple-slash-reference.js rename to packages/eslint-plugin/tests/rules/no-triple-slash-reference.ts index 5e61a3736c0c..f33b2bc1a9d7 100644 --- a/packages/eslint-plugin/tests/lib/rules/no-triple-slash-reference.js +++ b/packages/eslint-plugin/tests/rules/no-triple-slash-reference.ts @@ -2,14 +2,13 @@ * @fileoverview Enforces triple slash references are not used * @author Danny Fritz */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/no-triple-slash-reference'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/no-triple-slash-reference'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/lib/rules/no-type-alias.js b/packages/eslint-plugin/tests/rules/no-type-alias.ts similarity index 93% rename from packages/eslint-plugin/tests/lib/rules/no-type-alias.js rename to packages/eslint-plugin/tests/rules/no-type-alias.ts index fc3c91f7fa1d..8dac4f0c2d9f 100644 --- a/packages/eslint-plugin/tests/lib/rules/no-type-alias.js +++ b/packages/eslint-plugin/tests/rules/no-type-alias.ts @@ -2,14 +2,13 @@ * @fileoverview Disallows the use of type aliases. * @author Patricio Trevino */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/no-type-alias'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/no-type-alias'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests @@ -388,7 +387,7 @@ type Foo = { data: { alias: 'aliases' }, - row: 1, + line: 1, column: 12 } ] @@ -402,7 +401,7 @@ type Foo = { data: { alias: 'aliases' }, - row: 1, + line: 1, column: 12 } ] @@ -416,7 +415,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -425,7 +424,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 18 } ] @@ -440,7 +439,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -449,7 +448,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 18 } ] @@ -464,7 +463,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -473,7 +472,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 18 } ] @@ -488,7 +487,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -497,7 +496,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 18 } ] @@ -517,7 +516,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -526,7 +525,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 18 } ] @@ -540,7 +539,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -549,7 +548,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 18 }, { @@ -558,7 +557,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 24 } ] @@ -573,7 +572,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -582,7 +581,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 18 }, { @@ -591,7 +590,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 24 } ] @@ -606,7 +605,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -615,7 +614,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 18 }, { @@ -624,7 +623,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 24 } ] @@ -639,7 +638,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -648,7 +647,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 18 }, { @@ -657,7 +656,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 24 } ] @@ -672,7 +671,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -681,7 +680,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 18 }, { @@ -690,7 +689,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 24 } ] @@ -710,7 +709,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -719,7 +718,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 18 }, { @@ -728,7 +727,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 24 } ] @@ -742,7 +741,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 12 }, { @@ -751,7 +750,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 18 } ] @@ -766,7 +765,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 12 }, { @@ -775,7 +774,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 18 } ] @@ -790,7 +789,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 12 }, { @@ -799,7 +798,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 18 } ] @@ -814,7 +813,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 12 }, { @@ -823,7 +822,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 18 } ] @@ -838,7 +837,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 12 }, { @@ -847,7 +846,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 18 } ] @@ -867,7 +866,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 12 }, { @@ -876,7 +875,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 18 } ] @@ -890,7 +889,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 12 }, { @@ -899,7 +898,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 18 }, { @@ -908,7 +907,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 24 } ] @@ -923,7 +922,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 12 }, { @@ -932,7 +931,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 18 }, { @@ -941,7 +940,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 24 } ] @@ -956,7 +955,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 12 }, { @@ -965,7 +964,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 18 }, { @@ -974,7 +973,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 24 } ] @@ -989,7 +988,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 12 }, { @@ -998,7 +997,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 18 }, { @@ -1007,7 +1006,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 24 } ] @@ -1022,7 +1021,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 12 }, { @@ -1031,7 +1030,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 18 }, { @@ -1040,7 +1039,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 24 } ] @@ -1060,7 +1059,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 12 }, { @@ -1069,7 +1068,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 18 }, { @@ -1078,7 +1077,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 24 } ] @@ -1092,7 +1091,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -1101,7 +1100,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 18 }, { @@ -1110,7 +1109,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 24 } ] @@ -1125,7 +1124,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -1134,7 +1133,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 18 }, { @@ -1143,7 +1142,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 24 } ] @@ -1158,7 +1157,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -1167,7 +1166,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 18 }, { @@ -1176,7 +1175,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 24 } ] @@ -1191,7 +1190,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -1200,7 +1199,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 18 }, { @@ -1209,7 +1208,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 24 } ] @@ -1224,7 +1223,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 18 }, { @@ -1233,7 +1232,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 24 } ] @@ -1253,7 +1252,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 18 }, { @@ -1262,7 +1261,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 24 } ] @@ -1277,7 +1276,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 } ] @@ -1297,7 +1296,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 } ] @@ -1310,7 +1309,7 @@ type Foo = { data: { alias: 'aliases' }, - row: 1, + line: 1, column: 12 } ] @@ -1324,7 +1323,7 @@ type Foo = { data: { alias: 'aliases' }, - row: 1, + line: 1, column: 12 } ] @@ -1338,7 +1337,7 @@ type Foo = { data: { alias: 'aliases' }, - row: 1, + line: 1, column: 12 } ] @@ -1352,7 +1351,7 @@ type Foo = { data: { alias: 'aliases' }, - row: 1, + line: 1, column: 12 } ] @@ -1366,7 +1365,7 @@ type Foo = { data: { alias: 'aliases' }, - row: 1, + line: 1, column: 12 } ] @@ -1380,7 +1379,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -1389,7 +1388,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 21 } ] @@ -1404,7 +1403,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -1413,7 +1412,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 21 } ] @@ -1428,7 +1427,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -1437,7 +1436,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 21 } ] @@ -1452,7 +1451,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -1461,7 +1460,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 21 } ] @@ -1476,7 +1475,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -1485,7 +1484,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 21 } ] @@ -1505,7 +1504,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -1514,7 +1513,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 21 } ] @@ -1528,7 +1527,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -1537,7 +1536,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 21 }, { @@ -1546,7 +1545,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 32 } ] @@ -1561,7 +1560,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -1570,7 +1569,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 21 }, { @@ -1579,7 +1578,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 32 } ] @@ -1594,7 +1593,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -1603,7 +1602,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 21 }, { @@ -1612,7 +1611,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 32 } ] @@ -1627,7 +1626,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -1636,7 +1635,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 21 }, { @@ -1645,7 +1644,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 32 } ] @@ -1660,7 +1659,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -1669,7 +1668,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 21 }, { @@ -1678,7 +1677,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 32 } ] @@ -1698,7 +1697,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -1707,7 +1706,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 21 }, { @@ -1716,7 +1715,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 32 } ] @@ -1730,7 +1729,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -1739,7 +1738,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 21 }, { @@ -1748,7 +1747,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 32 } ] @@ -1763,7 +1762,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -1772,7 +1771,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 21 }, { @@ -1781,7 +1780,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 32 } ] @@ -1796,7 +1795,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -1805,7 +1804,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 21 }, { @@ -1814,7 +1813,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 32 } ] @@ -1829,7 +1828,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -1838,7 +1837,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 21 }, { @@ -1847,7 +1846,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 32 } ] @@ -1862,7 +1861,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 21 }, { @@ -1871,7 +1870,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 32 } ] @@ -1886,7 +1885,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 21 }, { @@ -1895,7 +1894,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 32 } ] @@ -1910,7 +1909,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 } ] @@ -1930,7 +1929,7 @@ type Foo = { typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 12 } ] @@ -1946,7 +1945,7 @@ type Foo = Bar; data: { alias: 'aliases' }, - row: 1, + line: 3, column: 12 } ] @@ -1963,7 +1962,7 @@ type Foo = Bar; data: { alias: 'aliases' }, - row: 1, + line: 3, column: 12 } ] @@ -1980,7 +1979,7 @@ type Foo = Bar; data: { alias: 'aliases' }, - row: 1, + line: 3, column: 12 } ] @@ -1997,7 +1996,7 @@ type Foo = Bar; data: { alias: 'aliases' }, - row: 1, + line: 3, column: 12 } ] @@ -2014,7 +2013,7 @@ type Foo = Bar; data: { alias: 'aliases' }, - row: 1, + line: 3, column: 12 } ] @@ -2031,7 +2030,7 @@ type Foo = Bar | {}; typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 3, column: 12 }, { @@ -2040,7 +2039,7 @@ type Foo = Bar | {}; typeName: 'Literals', compositionType: 'union' }, - row: 1, + line: 3, column: 18 } ] @@ -2058,7 +2057,7 @@ type Foo = Bar | {}; typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 3, column: 12 }, { @@ -2067,7 +2066,7 @@ type Foo = Bar | {}; typeName: 'Literals', compositionType: 'union' }, - row: 1, + line: 3, column: 18 } ] @@ -2085,7 +2084,7 @@ type Foo = Bar | {}; typeName: 'Literals', compositionType: 'union' }, - row: 1, + line: 3, column: 18 } ] @@ -2103,7 +2102,7 @@ type Foo = Bar | {}; typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 3, column: 12 }, { @@ -2112,7 +2111,7 @@ type Foo = Bar | {}; typeName: 'Literals', compositionType: 'union' }, - row: 1, + line: 3, column: 18 } ] @@ -2130,7 +2129,7 @@ type Foo = Bar | {}; typeName: 'Literals', compositionType: 'union' }, - row: 1, + line: 3, column: 18 } ] @@ -2147,7 +2146,7 @@ type Foo = Bar & {}; typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 3, column: 12 }, { @@ -2156,7 +2155,7 @@ type Foo = Bar & {}; typeName: 'Literals', compositionType: 'intersection' }, - row: 1, + line: 3, column: 18 } ] @@ -2174,7 +2173,7 @@ type Foo = Bar & {}; typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 3, column: 12 }, { @@ -2183,7 +2182,7 @@ type Foo = Bar & {}; typeName: 'Literals', compositionType: 'intersection' }, - row: 1, + line: 3, column: 18 } ] @@ -2201,7 +2200,7 @@ type Foo = Bar & {}; typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 3, column: 12 }, { @@ -2210,7 +2209,7 @@ type Foo = Bar & {}; typeName: 'Literals', compositionType: 'intersection' }, - row: 1, + line: 3, column: 18 } ] @@ -2228,7 +2227,7 @@ type Foo = Bar & {}; typeName: 'Literals', compositionType: 'intersection' }, - row: 1, + line: 3, column: 18 } ] @@ -2246,7 +2245,7 @@ type Foo = Bar & {}; typeName: 'Literals', compositionType: 'intersection' }, - row: 1, + line: 3, column: 18 } ] @@ -2259,7 +2258,7 @@ type Foo = Bar & {}; data: { alias: 'callbacks' }, - row: 1, + line: 1, column: 12 } ] @@ -2273,7 +2272,7 @@ type Foo = Bar & {}; data: { alias: 'callbacks' }, - row: 1, + line: 1, column: 12 } ] @@ -2286,7 +2285,7 @@ type Foo = Bar & {}; data: { alias: 'literals' }, - row: 1, + line: 1, column: 12 } ] @@ -2300,7 +2299,7 @@ type Foo = Bar & {}; data: { alias: 'literals' }, - row: 1, + line: 1, column: 12 } ] @@ -2314,7 +2313,7 @@ type Foo = Bar & {}; data: { alias: 'literals' }, - row: 1, + line: 1, column: 12 } ] @@ -2328,7 +2327,7 @@ type Foo = Bar & {}; data: { alias: 'literals' }, - row: 1, + line: 1, column: 12 } ] @@ -2342,7 +2341,7 @@ type Foo = Bar & {}; data: { alias: 'literals' }, - row: 1, + line: 1, column: 12 } ] @@ -2356,7 +2355,7 @@ type Foo = Bar & {}; data: { alias: 'literals' }, - row: 1, + line: 1, column: 12 } ] @@ -2370,7 +2369,7 @@ type Foo = Bar & {}; data: { alias: 'literals' }, - row: 1, + line: 1, column: 12 } ] @@ -2389,7 +2388,7 @@ type Foo = Bar & {}; data: { alias: 'literals' }, - row: 1, + line: 1, column: 12 } ] @@ -2408,7 +2407,7 @@ type Foo = Bar & {}; data: { alias: 'literals' }, - row: 1, + line: 1, column: 12 } ] @@ -2427,7 +2426,7 @@ type Foo = Bar & {}; data: { alias: 'literals' }, - row: 1, + line: 1, column: 12 } ] @@ -2441,7 +2440,7 @@ type Foo = Bar & {}; typeName: 'Literals', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -2450,7 +2449,7 @@ type Foo = Bar & {}; typeName: 'Literals', compositionType: 'union' }, - row: 1, + line: 1, column: 17 } ] @@ -2465,7 +2464,7 @@ type Foo = Bar & {}; typeName: 'Literals', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -2474,7 +2473,7 @@ type Foo = Bar & {}; typeName: 'Literals', compositionType: 'union' }, - row: 1, + line: 1, column: 17 } ] @@ -2489,7 +2488,7 @@ type Foo = Bar & {}; typeName: 'Literals', compositionType: 'union' }, - row: 1, + line: 1, column: 12 }, { @@ -2498,7 +2497,7 @@ type Foo = Bar & {}; typeName: 'Literals', compositionType: 'union' }, - row: 1, + line: 1, column: 17 } ] @@ -2512,7 +2511,7 @@ type Foo = Bar & {}; typeName: 'Literals', compositionType: 'intersection' }, - row: 1, + line: 1, column: 12 }, { @@ -2521,7 +2520,7 @@ type Foo = Bar & {}; typeName: 'Literals', compositionType: 'intersection' }, - row: 1, + line: 1, column: 17 } ] @@ -2536,7 +2535,7 @@ type Foo = Bar & {}; typeName: 'Literals', compositionType: 'intersection' }, - row: 1, + line: 1, column: 12 }, { @@ -2545,7 +2544,7 @@ type Foo = Bar & {}; typeName: 'Literals', compositionType: 'intersection' }, - row: 1, + line: 1, column: 17 } ] @@ -2560,7 +2559,7 @@ type Foo = Bar & {}; typeName: 'Literals', compositionType: 'intersection' }, - row: 1, + line: 1, column: 12 }, { @@ -2569,7 +2568,7 @@ type Foo = Bar & {}; typeName: 'Literals', compositionType: 'intersection' }, - row: 1, + line: 1, column: 17 } ] @@ -2584,7 +2583,7 @@ type Foo = Bar & {}; typeName: 'Aliases', compositionType: 'intersection' }, - row: 1, + line: 1, column: 12 }, { @@ -2593,7 +2592,7 @@ type Foo = Bar & {}; typeName: 'Literals', compositionType: 'intersection' }, - row: 1, + line: 1, column: 21 } ] @@ -2613,7 +2612,7 @@ type Foo = Bar & {}; typeName: 'Literals', compositionType: 'intersection' }, - row: 1, + line: 1, column: 21 }, { @@ -2622,7 +2621,7 @@ type Foo = Bar & {}; typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 26 }, { @@ -2631,7 +2630,7 @@ type Foo = Bar & {}; typeName: 'Aliases', compositionType: 'union' }, - row: 1, + line: 1, column: 32 } ] @@ -2648,7 +2647,7 @@ type Foo = { data: { alias: 'mapped types' }, - row: 1, + line: 2, column: 15 } ] @@ -2666,7 +2665,7 @@ type Foo = { data: { alias: 'mapped types' }, - row: 1, + line: 2, column: 15 } ] @@ -2684,7 +2683,7 @@ type Foo = { data: { alias: 'mapped types' }, - row: 1, + line: 2, column: 15 } ] @@ -2702,7 +2701,7 @@ type Foo = { data: { alias: 'mapped types' }, - row: 1, + line: 2, column: 15 } ] @@ -2720,7 +2719,7 @@ type Foo = { data: { alias: 'mapped types' }, - row: 1, + line: 2, column: 15 } ] @@ -2740,7 +2739,7 @@ type Foo = { typeName: 'Mapped types', compositionType: 'union' }, - row: 1, + line: 2, column: 15 }, { @@ -2749,7 +2748,7 @@ type Foo = { typeName: 'Mapped types', compositionType: 'union' }, - row: 4, + line: 4, column: 5 } ] @@ -2770,7 +2769,7 @@ type Foo = { typeName: 'Mapped types', compositionType: 'union' }, - row: 1, + line: 2, column: 15 }, { @@ -2779,7 +2778,7 @@ type Foo = { typeName: 'Mapped types', compositionType: 'union' }, - row: 4, + line: 4, column: 5 } ] @@ -2800,7 +2799,7 @@ type Foo = { typeName: 'Mapped types', compositionType: 'union' }, - row: 1, + line: 2, column: 15 }, { @@ -2809,7 +2808,7 @@ type Foo = { typeName: 'Mapped types', compositionType: 'union' }, - row: 4, + line: 4, column: 5 } ] @@ -2829,7 +2828,7 @@ type Foo = { typeName: 'Mapped types', compositionType: 'intersection' }, - row: 1, + line: 2, column: 15 }, { @@ -2838,7 +2837,7 @@ type Foo = { typeName: 'Mapped types', compositionType: 'intersection' }, - row: 4, + line: 4, column: 5 } ] @@ -2859,7 +2858,7 @@ type Foo = { typeName: 'Mapped types', compositionType: 'intersection' }, - row: 1, + line: 2, column: 15 }, { @@ -2868,7 +2867,7 @@ type Foo = { typeName: 'Mapped types', compositionType: 'intersection' }, - row: 4, + line: 4, column: 5 } ] @@ -2889,7 +2888,7 @@ type Foo = { typeName: 'Mapped types', compositionType: 'intersection' }, - row: 1, + line: 2, column: 15 }, { @@ -2898,7 +2897,7 @@ type Foo = { typeName: 'Mapped types', compositionType: 'intersection' }, - row: 4, + line: 4, column: 5 } ] diff --git a/packages/eslint-plugin/tests/lib/rules/no-unused-vars.js b/packages/eslint-plugin/tests/rules/no-unused-vars.ts similarity index 99% rename from packages/eslint-plugin/tests/lib/rules/no-unused-vars.js rename to packages/eslint-plugin/tests/rules/no-unused-vars.ts index 726f755c3956..c99b7caf5648 100644 --- a/packages/eslint-plugin/tests/lib/rules/no-unused-vars.js +++ b/packages/eslint-plugin/tests/rules/no-unused-vars.ts @@ -2,14 +2,13 @@ * @fileoverview Prevent variables used in TypeScript being marked as unused * @author James Henry */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/no-unused-vars'); -const RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/no-unused-vars'; +import { RuleTester } from 'eslint'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/lib/rules/no-use-before-define.js b/packages/eslint-plugin/tests/rules/no-use-before-define.ts similarity index 99% rename from packages/eslint-plugin/tests/lib/rules/no-use-before-define.js rename to packages/eslint-plugin/tests/rules/no-use-before-define.ts index b74645208d6d..674884dae2f1 100644 --- a/packages/eslint-plugin/tests/lib/rules/no-use-before-define.js +++ b/packages/eslint-plugin/tests/rules/no-use-before-define.ts @@ -4,14 +4,12 @@ * @author Jed Fox */ -'use strict'; - //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/no-use-before-define'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/no-use-before-define'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/lib/rules/no-var-requires.js b/packages/eslint-plugin/tests/rules/no-var-requires.ts similarity index 91% rename from packages/eslint-plugin/tests/lib/rules/no-var-requires.js rename to packages/eslint-plugin/tests/rules/no-var-requires.ts index 64662f95de2b..4dbd769c6475 100644 --- a/packages/eslint-plugin/tests/lib/rules/no-var-requires.js +++ b/packages/eslint-plugin/tests/rules/no-var-requires.ts @@ -2,14 +2,13 @@ * @fileoverview Disallows the use of require statements except in import statements. * @author Macklin Underdown */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/no-var-requires'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/no-var-requires'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/lib/rules/prefer-interface.js b/packages/eslint-plugin/tests/rules/prefer-interface.ts similarity index 93% rename from packages/eslint-plugin/tests/lib/rules/prefer-interface.js rename to packages/eslint-plugin/tests/rules/prefer-interface.ts index 1617cdbe6877..9a770b5e6eeb 100644 --- a/packages/eslint-plugin/tests/lib/rules/prefer-interface.js +++ b/packages/eslint-plugin/tests/rules/prefer-interface.ts @@ -2,14 +2,13 @@ * @fileoverview Prefer an interface declaration over a type literal (type T = { ... }) * @author Armano */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/prefer-interface'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/prefer-interface'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/lib/rules/prefer-namespace-keyword.js b/packages/eslint-plugin/tests/rules/prefer-namespace-keyword.ts similarity index 90% rename from packages/eslint-plugin/tests/lib/rules/prefer-namespace-keyword.js rename to packages/eslint-plugin/tests/rules/prefer-namespace-keyword.ts index 6107dc0d2ff0..9ff5e4b0db47 100644 --- a/packages/eslint-plugin/tests/lib/rules/prefer-namespace-keyword.js +++ b/packages/eslint-plugin/tests/rules/prefer-namespace-keyword.ts @@ -3,14 +3,13 @@ * @author Patricio Trevino * @author Armano */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/prefer-namespace-keyword'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/prefer-namespace-keyword'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests @@ -36,7 +35,7 @@ ruleTester.run('prefer-namespace-keyword', rule, { { message: "Use 'namespace' instead of 'module' to declare custom TypeScript modules.", - row: 1, + line: 1, column: 1 } ] @@ -48,7 +47,7 @@ ruleTester.run('prefer-namespace-keyword', rule, { { message: "Use 'namespace' instead of 'module' to declare custom TypeScript modules.", - row: 1, + line: 1, column: 1 } ] @@ -68,13 +67,13 @@ declare namespace foo { { message: "Use 'namespace' instead of 'module' to declare custom TypeScript modules.", - row: 2, + line: 2, column: 1 }, { message: "Use 'namespace' instead of 'module' to declare custom TypeScript modules.", - row: 3, + line: 3, column: 5 } ] diff --git a/packages/eslint-plugin/tests/lib/rules/restrict-plus-operands.js b/packages/eslint-plugin/tests/rules/restrict-plus-operands.ts similarity index 97% rename from packages/eslint-plugin/tests/lib/rules/restrict-plus-operands.js rename to packages/eslint-plugin/tests/rules/restrict-plus-operands.ts index d5a07e596982..17da3c49b7b8 100644 --- a/packages/eslint-plugin/tests/lib/rules/restrict-plus-operands.js +++ b/packages/eslint-plugin/tests/rules/restrict-plus-operands.ts @@ -3,15 +3,14 @@ * @author James Henry * @author Armano */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ const path = require('path'); -const rule = require('../../../lib/rules/restrict-plus-operands'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/restrict-plus-operands'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/lib/rules/type-annotation-spacing.js b/packages/eslint-plugin/tests/rules/type-annotation-spacing.ts similarity index 99% rename from packages/eslint-plugin/tests/lib/rules/type-annotation-spacing.js rename to packages/eslint-plugin/tests/rules/type-annotation-spacing.ts index b5826a54e29f..d5d43d4b0242 100644 --- a/packages/eslint-plugin/tests/lib/rules/type-annotation-spacing.js +++ b/packages/eslint-plugin/tests/rules/type-annotation-spacing.ts @@ -2,14 +2,13 @@ * @fileoverview Enforces spacing around type annotations * @author Nicholas C. Zakas */ -'use strict'; //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/type-annotation-spacing'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/type-annotation-spacing'; +import { RuleTester } from 'eslint'; //------------------------------------------------------------------------------ // Tests @@ -5962,7 +5961,7 @@ type Foo = { const operators = ['+?:', '-?:']; ruleTester.run('type-annotation-spacing', rule, { - valid: operators.reduce( + valid: operators.reduce( (validCases, operator) => validCases.concat([ { @@ -6004,9 +6003,9 @@ ruleTester.run('type-annotation-spacing', rule, { ]), [] ), - invalid: operators.reduce( - (validCases, operator) => - validCases.concat([ + invalid: operators.reduce( + (invalidCases, operator) => + invalidCases.concat([ // space before + after cases { code: `type Foo = { [P in keyof T] ${operator} T[P] }`, diff --git a/packages/eslint-plugin/tests/lib/util.js b/packages/eslint-plugin/tests/util.ts similarity index 96% rename from packages/eslint-plugin/tests/lib/util.js rename to packages/eslint-plugin/tests/util.ts index 4f627c5dc11b..4781d86a79e3 100644 --- a/packages/eslint-plugin/tests/lib/util.js +++ b/packages/eslint-plugin/tests/util.ts @@ -1,7 +1,6 @@ -'use strict'; -const assert = require('assert'); +import assert from 'assert'; -const util = require('../../lib/util'); +import * as util from '../src/util'; describe('isTypescript', () => { it('returns false for non-typescript files', () => { @@ -172,8 +171,8 @@ describe('applyDefault', () => { }); it('returns a brand new array', () => { - const defaults = []; - const user = []; + const defaults: undefined[] = []; + const user: undefined[] = []; const result = util.applyDefault(defaults, user); assert.notStrictEqual(result, defaults); diff --git a/packages/eslint-plugin/typings/eslint.d.ts b/packages/eslint-plugin/typings/eslint.d.ts index e3971da89141..4cccafbfb7e6 100644 --- a/packages/eslint-plugin/typings/eslint.d.ts +++ b/packages/eslint-plugin/typings/eslint.d.ts @@ -1,11 +1,20 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ // module augmentation is weird -import { Scope } from 'eslint'; +import { RuleTester, Scope } from 'eslint'; declare module 'eslint' { namespace Scope { interface Variable { eslintUsed: boolean; } } + + export interface RuleTesterRunTests { + // RuleTester.run also accepts strings for valid cases + valid: (RuleTester.ValidTestCase | string)[]; + invalid: RuleTester.InvalidTestCase[]; + } + interface RuleTester { + run(name: string, rule: Rule.RuleModule, tests: RuleTesterRunTests): void; + } } From fd3fc9db273d19a306228770648face272c0e463 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Thu, 24 Jan 2019 19:10:46 -0800 Subject: [PATCH 10/92] started adding type defs for TSEstree --- packages/typescript-estree/src/convert.ts | 4 +- packages/typescript-estree/src/typedefs.ts | 203 +++++++++++++++++++++ 2 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 packages/typescript-estree/src/typedefs.ts diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 64120d6a8d85..48e92a8d545f 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -253,7 +253,9 @@ export default function convert(config: ConvertConfig): ESTreeNode | null { * @param {ts.Node[]} parameters An array of ts.Node params to be converted * @returns {ESTreeNode[]} an array of converted ESTreeNode params */ - function convertParameters(parameters: ts.NodeArray): ESTreeNode[] { + function convertParameters( + parameters: ts.NodeArray + ): ESTreeNode[] { if (!parameters || !parameters.length) { return []; } diff --git a/packages/typescript-estree/src/typedefs.ts b/packages/typescript-estree/src/typedefs.ts new file mode 100644 index 000000000000..5eaac1d1e5b3 --- /dev/null +++ b/packages/typescript-estree/src/typedefs.ts @@ -0,0 +1,203 @@ +interface LineAndColumnData { + /** + * Line number (1-indexed) + */ + line: number; + /** + * Column number on the line (0-indexed) + */ + column: number; +} + +interface NodeBase { + /** + * The source location information of the node. + */ + loc: { + /** + * The position of the first character of the parsed source region + */ + start: LineAndColumnData; + /** + * The position of the first character after the parsed source region + */ + end: LineAndColumnData; + }; + /** + * An array of two numbers. + * Both numbers are a 0-based index which is the position in the array of source code characters. + * The first is the start position of the node, the second is the end position of the node. + */ + range: [number, number]; + + // every node *will* have a type, but let the nodes define their own exact string + // type: string; + + // we don't ever set this from within ts-estree + // source?: string | null; +} + +interface NodeWithTypeAnnotation extends NodeBase { + typeAnnotation: TSTypeAnnotation; +} + +// NOTE - got to VariableStatement - line 681 + +// ensure you sort the union members alphabetically... +type ESTreeNode = null; + +type BindingPattern = ArrayPattern | ObjectPattern; +type BindingName = Identifier | BindingPattern; +type Expression = null; // TODO - get lists from ts source and convert to estree nodes +type ForInitialiser = Expression | VariableDeclaration; +type Parameter = AssignmentPattern | RestElement | TSParameterProperty; +type Statement = null; // TODO - get lists from ts source and convert to estree nodes + +// ensure you sort the following interfaces alphabetically + +interface BlockStatement extends NodeBase { + type: 'BlockStatement'; + body: Statement[]; +} + +interface BreakStatement extends NodeBase { + type: 'BreakStatement'; + label: Identifier | null; +} + +interface CatchClause extends NodeBase { + type: 'CatchClause'; + param: BindingName | null; + body: BlockStatement; +} + +interface ContinueStatement extends NodeBase { + type: 'ContinueStatement'; + label: Identifier | null; +} + +interface DoWhileStatement extends NodeBase { + type: 'DoWhileStatement'; + test: Expression; + body: Statement; +} + +interface ForInStatement extends NodeBase { + type: 'ForInStatement'; + left: ForInitialiser; + right: Expression; + body: Statement; +} + +interface ForOfStatement extends NodeBase { + type: 'ForOfStatement'; + left: ForInitialiser; + right: Expression; + body: Statement; + await: boolean; +} + +interface ForStatement extends NodeBase { + type: 'ForStatement'; + init: Expression | ForInitialiser | null; + test: Expression | null; + update: Expression | null; + body: Statement; +} + +interface FunctionDeclaration extends NodeBase { + type: 'FunctionDeclaration'; + id: Identifier | null; + generator: boolean; + expression: false; + async: boolean; + params: Parameter; + body: BlockStatement | null | undefined; + returnType?: TSTypeAnnotation; + typeParameters?: TSTypeParameterDeclaration; +} + +interface TSDeclareFunction extends NodeBase { + type: 'TSDeclareFunction'; + id: Identifier | null; + generator: boolean; + expression: false; + async: boolean; + params: Parameter; + body: BlockStatement | null | undefined; + returnType?: TSTypeAnnotation; + declare: true; + typeParameters?: TSTypeParameterDeclaration; +} + +interface Identifier extends NodeWithTypeAnnotation { + type: 'Identifier'; + name: string; +} + +interface IfStatement extends NodeBase { + type: 'IfStatement'; + test: Expression; + consequent: Statement; + alternate: Statement | null; +} + +interface LabeledStatement extends NodeBase { + type: 'LabeledStatement'; + label: Identifier; + body: Statement; +} + +interface Program extends NodeBase { + type: 'Program'; + body: Statement[]; + sourceType: 'module' | 'script'; +} + +interface ReturnStatement extends NodeBase { + type: 'ReturnStatement'; + argument: Expression | null; +} + +interface SwitchCase extends NodeBase { + type: 'SwitchCase'; + test: Expression; + consequent: Statement[]; +} + +interface SwitchStatement extends NodeBase { + type: 'SwitchStatement'; + discriminant: Expression; + cases: SwitchCase[]; +} + +interface ThrowStatement extends NodeBase { + type: 'ThrowStatement'; + argument: Statement | null; +} + +interface TryStatement extends NodeBase { + type: 'TryStatement'; + block: BlockStatement; + handler: CatchClause | null; + finalizer: BlockStatement; +} + +interface VariableDeclarator extends NodeBase { + type: 'VariableDeclarator'; + id: BindingName; + init: Expression | null; + definite?: boolean; +} + +interface WhileStatement extends NodeBase { + type: 'WhileStatement'; + test: Expression; + body: Statement; +} + +interface WithStatement extends NodeBase { + type: 'WithStatement'; + object: Expression; + body: Statement; +} From 9bfbb86125c1d7c4ebe200ef1adec6462f0673e8 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Fri, 25 Jan 2019 10:16:50 -0800 Subject: [PATCH 11/92] more types --- packages/typescript-estree/src/typedefs.ts | 125 +++++++++++++++++---- 1 file changed, 106 insertions(+), 19 deletions(-) diff --git a/packages/typescript-estree/src/typedefs.ts b/packages/typescript-estree/src/typedefs.ts index 5eaac1d1e5b3..0434ef62ab3c 100644 --- a/packages/typescript-estree/src/typedefs.ts +++ b/packages/typescript-estree/src/typedefs.ts @@ -37,11 +37,7 @@ interface NodeBase { // source?: string | null; } -interface NodeWithTypeAnnotation extends NodeBase { - typeAnnotation: TSTypeAnnotation; -} - -// NOTE - got to VariableStatement - line 681 +// NOTE - got to line 860 // ensure you sort the union members alphabetically... type ESTreeNode = null; @@ -50,11 +46,28 @@ type BindingPattern = ArrayPattern | ObjectPattern; type BindingName = Identifier | BindingPattern; type Expression = null; // TODO - get lists from ts source and convert to estree nodes type ForInitialiser = Expression | VariableDeclaration; +type ObjectLiteralElementLike = + | MethodDefinition + | Property + | RestElement + | SpreadElement + | TSAbstractMethodDefinition; type Parameter = AssignmentPattern | RestElement | TSParameterProperty; +type PropertyName = Identifier | Literal; type Statement = null; // TODO - get lists from ts source and convert to estree nodes // ensure you sort the following interfaces alphabetically +interface ArrayExpression extends NodeBase { + type: 'ArrayExpression'; + elements: Expression[]; +} + +interface ArrayPattern extends NodeBase { + type: 'ArrayPattern'; + elements: Expression[]; +} + interface BlockStatement extends NodeBase { type: 'BlockStatement'; body: Statement[]; @@ -71,6 +84,20 @@ interface CatchClause extends NodeBase { body: BlockStatement; } +interface ClassProperty extends NodeBase { + type: 'ClassProperty'; + key: PropertyName; + value: Expression; + computed: boolean; + static: boolean; + readonly: boolean | undefined; + decorators?: Decorator[]; + accessibility?: 'public' | 'protected' | 'private'; + optional?: boolean; + definite?: boolean; + typeAnnotation?: TSTypeAnnotation; +} + interface ContinueStatement extends NodeBase { type: 'ContinueStatement'; label: Identifier | null; @@ -82,6 +109,24 @@ interface DoWhileStatement extends NodeBase { body: Statement; } +interface ExportDefaultDeclaration extends NodeBase { + type: 'ExportDefaultDeclaration'; + declaration: Node; +} + +interface ExportNamedDeclaration extends NodeBase { + type: 'ExportNamedDeclaration'; + declaration: Node; + // we don't put anything in these? + specifiers: never[]; + source: null; +} + +interface ExpressionStatement extends NodeBase { + type: 'ExpressionStatement'; + expression: Expression; +} + interface ForInStatement extends NodeBase { type: 'ForInStatement'; left: ForInitialiser; @@ -117,22 +162,10 @@ interface FunctionDeclaration extends NodeBase { typeParameters?: TSTypeParameterDeclaration; } -interface TSDeclareFunction extends NodeBase { - type: 'TSDeclareFunction'; - id: Identifier | null; - generator: boolean; - expression: false; - async: boolean; - params: Parameter; - body: BlockStatement | null | undefined; - returnType?: TSTypeAnnotation; - declare: true; - typeParameters?: TSTypeParameterDeclaration; -} - -interface Identifier extends NodeWithTypeAnnotation { +interface Identifier extends NodeBase { type: 'Identifier'; name: string; + typeAnnotation?: TSTypeAnnotation; } interface IfStatement extends NodeBase { @@ -148,12 +181,32 @@ interface LabeledStatement extends NodeBase { body: Statement; } +interface ObjectExpression extends NodeBase { + type: 'ObjectExpression'; + properties: ObjectLiteralElementLike[]; +} + +interface ObjectPattern extends NodeBase { + type: 'ObjectPattern'; + properties: ObjectLiteralElementLike[]; +} + interface Program extends NodeBase { type: 'Program'; body: Statement[]; sourceType: 'module' | 'script'; } +interface Property extends NodeBase { + type: 'Property'; + key: PropertyName; + value: Expression | AssignmentPattern; // TODO + computed: boolean; + method: boolean; + shorthand: boolean; + kind: 'init'; +} + interface ReturnStatement extends NodeBase { type: 'ReturnStatement'; argument: Expression | null; @@ -183,6 +236,40 @@ interface TryStatement extends NodeBase { finalizer: BlockStatement; } +interface TSAbstractClassProperty extends NodeBase { + type: 'TSAbstractClassProperty'; + key: PropertyName; + value: Expression; + computed: boolean; + static: boolean; + readonly: boolean | undefined; + decorators?: Decorator[]; + accessibility?: 'public' | 'protected' | 'private'; + optional?: boolean; + definite?: boolean; + typeAnnotation?: TSTypeAnnotation; +} + +interface TSDeclareFunction extends NodeBase { + type: 'TSDeclareFunction'; + id: Identifier | null; + generator: boolean; + expression: false; + async: boolean; + params: Parameter; + body: BlockStatement | null | undefined; + returnType?: TSTypeAnnotation; + declare: true; + typeParameters?: TSTypeParameterDeclaration; +} + +interface VariableDeclaration extends NodeBase { + type: 'VariableDeclaration'; + declarations: VariableDeclarator[]; + kind: 'let' | 'const' | 'var'; + declare?: boolean; +} + interface VariableDeclarator extends NodeBase { type: 'VariableDeclarator'; id: BindingName; From a47e536804d0816ea4b5be53f767e2a2ac68e84b Mon Sep 17 00:00:00 2001 From: Armano Date: Sat, 26 Jan 2019 02:55:23 +0100 Subject: [PATCH 12/92] chore(ts-estree): draft of estree structure (replacement for ESTreeNode) (#137) --- .../typescript-estree/src/es-tree-nodes.ts | 1223 +++++++++++++++++ 1 file changed, 1223 insertions(+) create mode 100644 packages/typescript-estree/src/es-tree-nodes.ts diff --git a/packages/typescript-estree/src/es-tree-nodes.ts b/packages/typescript-estree/src/es-tree-nodes.ts new file mode 100644 index 000000000000..5dffb31f744a --- /dev/null +++ b/packages/typescript-estree/src/es-tree-nodes.ts @@ -0,0 +1,1223 @@ +/** + * @fileoverview Definition of AST structure. + * @author Armano + */ + +export interface Position { + line: number; + column: number; +} + +interface SourceLocation { + source?: string | null; + start: Position; + end: Position; +} + +export interface BaseNode { + type: string; + loc?: SourceLocation | null; + range?: [number, number]; +} + +export interface Comment extends BaseNode { + type: 'Line' | 'Block'; + value: string; +} + +export interface ArrayExpression extends BaseNode { + type: 'ArrayExpression'; + elements: Array; +} + +export interface ArrayPattern extends BaseNode { + type: 'ArrayPattern'; + optional?: boolean; + typeAnnotation?: TSTypeAnnotation; + elements: Array< + | ArrayPattern + | AssignmentPattern + | Identifier + | MemberExpression + | ObjectPattern + | RestElement + | null + >; +} + +export interface ArrowFunctionExpression extends BaseNode { + type: 'ArrowFunctionExpression'; + generator: boolean; + expression: boolean; + async: boolean; + typeParameters?: TSTypeParameterDeclaration; + returnType?: TSTypeAnnotation; + params: Array< + | ArrayPattern + | AssignmentPattern + | Identifier + | ObjectPattern + | RestElement + | TSParameterProperty + >; + id: null; + body: BlockStatement | Expressions | Identifier | JSXElement | Literals; +} + +export interface AssignmentExpression extends BaseNode { + type: 'AssignmentExpression'; + operator: + | '%=' + | '&=' + | '**=' + | '*=' + | '+=' + | '-=' + | '/=' + | '<<=' + | '=' + | '>>=' + | '>>>=' + | '^=' + | '|='; + right: Expressions | Identifier | JSXElement | Literals; + left: ArrayPattern | Expressions | Identifier | Literal | ObjectPattern; +} + +export interface AssignmentPattern extends BaseNode { + type: 'AssignmentPattern'; + right: Expressions | Identifier | Literals; + left: ArrayPattern | Identifier | ObjectPattern; +} + +export interface AwaitExpression extends BaseNode { + type: 'AwaitExpression'; + argument: Expressions | Identifier | Literal; +} + +export interface BigIntLiteral extends BaseNode { + type: 'BigIntLiteral'; + value: string; + raw: string; +} + +export interface BinaryExpression extends BaseNode { + type: 'BinaryExpression'; + operator: + | '!=' + | '!==' + | '%' + | '&' + | '*' + | '**' + | '+' + | '-' + | '/' + | '<' + | '<<' + | '<=' + | '==' + | '===' + | '>' + | '>=' + | '>>' + | '>>>' + | '^' + | 'in' + | 'instanceof' + | '|'; + right: Expressions | Identifier | Literals; + left: Expressions | Identifier | Literals; +} + +export interface BlockStatement extends BaseNode { + type: 'BlockStatement'; + body: Array; +} + +export interface BreakStatement extends BaseNode { + type: 'BreakStatement'; + label: null | Identifier; +} + +export interface CallExpression extends BaseNode { + type: 'CallExpression'; + typeParameters?: TSTypeParameterInstantiation; + callee: Expressions | Identifier | Import | Literals | Super; + arguments: Array; +} + +export interface CatchClause extends BaseNode { + type: 'CatchClause'; + param: null | ArrayPattern | Identifier | ObjectPattern; + body: BlockStatement; +} + +export interface ClassBody extends BaseNode { + type: 'ClassBody'; + body: Array< + | ClassProperty + | MethodDefinition + | TSAbstractClassProperty + | TSAbstractMethodDefinition + | TSIndexSignature + >; +} + +export interface ClassDeclaration extends BaseNode { + type: 'ClassDeclaration'; + declare?: boolean; + abstract?: boolean; + typeParameters?: TSTypeParameterDeclaration; + superTypeParameters?: TSTypeParameterInstantiation; + superClass: null | Expressions | Identifier | Literal; + implements?: Array; + id: null | Identifier; + decorators?: Array; + body: ClassBody; +} + +export interface ClassExpression extends BaseNode { + type: 'ClassExpression'; + typeParameters?: TSTypeParameterDeclaration; + superTypeParameters?: TSTypeParameterInstantiation; + superClass: null | Expressions | Identifier; + implements?: Array; + id: null | Identifier; + body: ClassBody; +} + +export interface ClassProperty extends BaseNode { + type: 'ClassProperty'; + static: boolean; + readonly?: boolean; + optional?: boolean; + definite?: boolean; + computed: boolean; + accessibility?: 'private' | 'protected' | 'public'; + value: null | Expressions | Identifier | Literal; + typeAnnotation?: TSTypeAnnotation; + key: Expressions | Identifier | Literals; + decorators?: Array; +} + +export interface ConditionalExpression extends BaseNode { + type: 'ConditionalExpression'; + test: Expressions | Identifier | Literals; + consequent: Expressions | Identifier | JSXElement | Literals; + alternate: Expressions | Identifier | JSXElement | Literals; +} + +export interface ContinueStatement extends BaseNode { + type: 'ContinueStatement'; + label: null | Identifier; +} + +export interface DebuggerStatement extends BaseNode { + type: 'DebuggerStatement'; +} + +export interface Decorator extends BaseNode { + type: 'Decorator'; + expression: Expressions | Identifier; +} + +export interface DoWhileStatement extends BaseNode { + type: 'DoWhileStatement'; + test: Expressions | Identifier | Literal; + body: BlockStatement | VariableDeclaration; +} + +export interface EmptyStatement extends BaseNode { + type: 'EmptyStatement'; +} + +export interface ExportAllDeclaration extends BaseNode { + type: 'ExportAllDeclaration'; + source: Identifier | Literal; +} + +export interface ExportDefaultDeclaration extends BaseNode { + type: 'ExportDefaultDeclaration'; + declaration: Declarations | Expressions | Identifier | JSXElement | Literal; +} + +export interface ExportNamedDeclaration extends BaseNode { + type: 'ExportNamedDeclaration'; + specifiers: Array; + source: null | Literal; + declaration: null | Declarations; +} + +export interface ExportSpecifier extends BaseNode { + type: 'ExportSpecifier'; + local: Identifier; + exported: Identifier; +} + +export interface ExpressionStatement extends BaseNode { + type: 'ExpressionStatement'; + directive?: string; + expression: Expressions | Identifier | JSXElement | JSXFragment | Literals; +} + +export interface ForInStatement extends BaseNode { + type: 'ForInStatement'; + right: Expressions | Identifier | Literal; + left: + | AssignmentPattern + | Expressions + | Identifier + | ObjectPattern + | VariableDeclaration; + body: Statements | VariableDeclaration; +} + +export interface ForOfStatement extends BaseNode { + type: 'ForOfStatement'; + await: boolean; + right: Expressions | Identifier | Literal; + left: + | ArrayPattern + | Expressions + | Identifier + | ObjectPattern + | VariableDeclaration; + body: Statements; +} + +export interface ForStatement extends BaseNode { + type: 'ForStatement'; + update: null | Expressions | Identifier; + test: null | Expressions | Identifier | Literal; + init: null | Expressions | Identifier | VariableDeclaration; + body: Statements | VariableDeclaration; +} + +export interface FunctionDeclaration extends BaseNode { + type: 'FunctionDeclaration'; + generator: boolean; + expression: boolean; + async: boolean; + typeParameters?: TSTypeParameterDeclaration; + returnType?: TSTypeAnnotation; + params: Array< + | ArrayPattern + | AssignmentPattern + | Identifier + | ObjectPattern + | RestElement + | TSParameterProperty + >; + id: null | Identifier; + body: BlockStatement; +} + +export interface FunctionExpression extends BaseNode { + type: 'FunctionExpression'; + generator: boolean; + expression: boolean; + async: boolean; + typeParameters?: TSTypeParameterDeclaration; + returnType?: TSTypeAnnotation; + params: Array< + | ArrayPattern + | AssignmentPattern + | Identifier + | ObjectPattern + | RestElement + | TSParameterProperty + >; + id: null | Identifier; + body: null | BlockStatement; +} + +export interface Identifier extends BaseNode { + type: 'Identifier'; + optional?: boolean; + name: string; + typeAnnotation?: TSTypeAnnotation; + decorators?: Array; +} + +export interface IfStatement extends BaseNode { + type: 'IfStatement'; + test: Expressions | Identifier | Literal; + consequent: Statements | VariableDeclaration; + alternate: null | Statements | VariableDeclaration; +} + +export interface Import extends BaseNode { + type: 'Import'; +} + +export interface ImportDeclaration extends BaseNode { + type: 'ImportDeclaration'; + specifiers: Array< + ImportDefaultSpecifier | ImportNamespaceSpecifier | ImportSpecifier + >; + source: Literal; +} + +export interface ImportDefaultSpecifier extends BaseNode { + type: 'ImportDefaultSpecifier'; + local: Identifier; +} + +export interface ImportNamespaceSpecifier extends BaseNode { + type: 'ImportNamespaceSpecifier'; + local: Identifier; +} + +export interface ImportSpecifier extends BaseNode { + type: 'ImportSpecifier'; + local: Identifier; + imported: Identifier; +} + +export interface JSXAttribute extends BaseNode { + type: 'JSXAttribute'; + value: null | JSXExpressionContainer | Literal; + name: JSXIdentifier; +} + +export interface JSXClosingElement extends BaseNode { + type: 'JSXClosingElement'; + name: JSXIdentifier | JSXMemberExpression; +} + +export interface JSXClosingFragment extends BaseNode { + type: 'JSXClosingFragment'; +} + +export interface JSXElement extends BaseNode { + type: 'JSXElement'; + openingElement: JSXOpeningElement; + closingElement: null | JSXClosingElement; + children: Array< + JSXElement | JSXExpressionContainer | JSXFragment | JSXSpreadChild | JSXText + >; +} + +export interface JSXEmptyExpression extends BaseNode { + type: 'JSXEmptyExpression'; +} + +export interface JSXExpressionContainer extends BaseNode { + type: 'JSXExpressionContainer'; + expression: + | Expressions + | Identifier + | JSXElement + | JSXEmptyExpression + | Literal; +} + +export interface JSXFragment extends BaseNode { + type: 'JSXFragment'; + openingFragment: JSXOpeningFragment; + closingFragment: JSXClosingFragment; + children: Array; +} + +export interface JSXIdentifier extends BaseNode { + type: 'JSXIdentifier'; + name: string; +} + +export interface JSXMemberExpression extends BaseNode { + type: 'JSXMemberExpression'; + property: JSXIdentifier; + object: JSXIdentifier | JSXMemberExpression | MemberExpression; +} + +export interface JSXOpeningElement extends BaseNode { + type: 'JSXOpeningElement'; + selfClosing: boolean; + typeParameters?: TSTypeParameterInstantiation; + name: JSXIdentifier | JSXMemberExpression; + attributes: Array; +} + +export interface JSXOpeningFragment extends BaseNode { + type: 'JSXOpeningFragment'; +} + +export interface JSXSpreadAttribute extends BaseNode { + type: 'JSXSpreadAttribute'; + argument: Expressions | Identifier; +} + +export interface JSXSpreadChild extends BaseNode { + type: 'JSXSpreadChild'; + expression: Expressions | JSXElement; +} + +export interface JSXText extends BaseNode { + type: 'JSXText'; + value: string; + raw: string; +} + +export interface LabeledStatement extends BaseNode { + type: 'LabeledStatement'; + label: Identifier; + body: Statements | VariableDeclaration; +} + +export interface Literal extends BaseNode { + type: 'Literal'; + value: boolean | null | number | string; + raw: string; + regex?: { + pattern: string; + flags: string; + }; +} + +export interface LogicalExpression extends BaseNode { + type: 'LogicalExpression'; + operator: '&&' | '||'; + right: Expressions | Identifier | Literal; + left: Expressions | Identifier | Literal; +} + +export interface MemberExpression extends BaseNode { + type: 'MemberExpression'; + computed: boolean; + property: Expressions | Identifier | Literals; + object: Expressions | Identifier | Literals | Super; +} + +export interface MetaProperty extends BaseNode { + type: 'MetaProperty'; + property: Identifier; + meta: Identifier; +} + +export interface MethodDefinition extends BaseNode { + type: 'MethodDefinition'; + static: boolean; + kind: 'constructor' | 'get' | 'method' | 'set'; + computed: boolean; + accessibility?: 'private' | 'protected' | 'public'; + value: FunctionExpression; + key: Expressions | Identifier | Literals; + decorators?: Array; +} + +export interface NewExpression extends BaseNode { + type: 'NewExpression'; + typeParameters?: TSTypeParameterInstantiation; + callee: Expressions | Identifier | Super | TemplateLiteral; + arguments: Array; +} + +export interface ObjectExpression extends BaseNode { + type: 'ObjectExpression'; + properties: Array; +} + +export interface ObjectPattern extends BaseNode { + type: 'ObjectPattern'; + optional?: boolean; + typeAnnotation?: TSTypeAnnotation; + properties: Array; +} + +export interface Program extends BaseNode { + type: 'Program'; + sourceType: 'module' | 'script'; + body: Array; +} + +export interface Property extends BaseNode { + type: 'Property'; + shorthand: boolean; + method: boolean; + kind: 'get' | 'init' | 'set'; + computed: boolean; + value: + | ArrayPattern + | AssignmentPattern + | Expressions + | Identifier + | Literals + | ObjectPattern; + typeParameters?: TSTypeParameterDeclaration; + key: Expressions | Identifier | Literals; +} + +export interface RestElement extends BaseNode { + type: 'RestElement'; + optional?: boolean; + typeAnnotation?: TSTypeAnnotation; + decorators?: Array; + argument: ArrayPattern | AssignmentPattern | Identifier | ObjectPattern; +} + +export interface ReturnStatement extends BaseNode { + type: 'ReturnStatement'; + argument: + | null + | Expressions + | Identifier + | JSXElement + | JSXFragment + | Literals; +} + +export interface SequenceExpression extends BaseNode { + type: 'SequenceExpression'; + expressions: Array; +} + +export interface SpreadElement extends BaseNode { + type: 'SpreadElement'; + argument: Expressions | Identifier; +} + +export interface Super extends BaseNode { + type: 'Super'; +} + +export interface SwitchCase extends BaseNode { + type: 'SwitchCase'; + test: null | Expressions | Identifier | Literals; + consequent: Array; +} + +export interface SwitchStatement extends BaseNode { + type: 'SwitchStatement'; + discriminant: Expressions | Identifier | Literals; + cases: Array; +} + +export interface TaggedTemplateExpression extends BaseNode { + type: 'TaggedTemplateExpression'; + typeParameters?: TSTypeParameterInstantiation; + tag: Identifier | MemberExpression | TemplateLiteral; + quasi: TemplateLiteral; +} + +export interface TemplateElement extends BaseNode { + type: 'TemplateElement'; + tail: boolean; + value: { + raw: string; + cooked: string; + }; +} + +export interface TemplateLiteral extends BaseNode { + type: 'TemplateLiteral'; + quasis: Array; + expressions: Array; +} + +export interface ThisExpression extends BaseNode { + type: 'ThisExpression'; +} + +export interface ThrowStatement extends BaseNode { + type: 'ThrowStatement'; + argument: null | Expressions | Identifier | Literal; +} + +export interface TryStatement extends BaseNode { + type: 'TryStatement'; + handler: null | CatchClause; + finalizer: null | BlockStatement; + block: BlockStatement; +} + +export interface UnaryExpression extends BaseNode { + type: 'UnaryExpression'; + prefix: boolean; + operator: '!' | '+' | '-' | 'delete' | 'typeof' | 'void' | '~'; + argument: Expressions | Identifier | Literals; +} + +export interface UpdateExpression extends BaseNode { + type: 'UpdateExpression'; + prefix: boolean; + operator: '++' | '--'; + argument: Expressions | Identifier | Literal; +} + +export interface VariableDeclaration extends BaseNode { + type: 'VariableDeclaration'; + kind: 'const' | 'let' | 'var'; + declare?: boolean; + declarations: Array; +} + +export interface VariableDeclarator extends BaseNode { + type: 'VariableDeclarator'; + definite?: boolean; + init: null | Expressions | Identifier | JSXElement | Literals; + id: ArrayPattern | Identifier | ObjectPattern; +} + +export interface WhileStatement extends BaseNode { + type: 'WhileStatement'; + test: Expressions | Identifier | Literals; + body: Statements | VariableDeclaration; +} + +export interface WithStatement extends BaseNode { + type: 'WithStatement'; + object: Expressions | Identifier | Literal; + body: Statements | VariableDeclaration; +} + +export interface YieldExpression extends BaseNode { + type: 'YieldExpression'; + delegate: boolean; + argument: null | Expressions | Identifier | Literals; +} + +export interface TSAbstractClassProperty extends BaseNode { + type: 'TSAbstractClassProperty'; + static: boolean; + readonly?: boolean; + optional?: boolean; + definite: boolean; + computed: boolean; + accessibility?: 'private' | 'protected' | 'public'; + value: null; + typeAnnotation?: TSTypeAnnotation; + key: Identifier; +} + +export interface TSAbstractMethodDefinition extends BaseNode { + type: 'TSAbstractMethodDefinition'; + static: boolean; + kind: 'constructor' | 'get' | 'method' | 'set'; + computed: boolean; + accessibility?: 'private' | 'protected' | 'public'; + value: FunctionExpression; + key: Identifier; +} + +export interface TSArrayType extends BaseNode { + type: 'TSArrayType'; + elementType: TSTypeKeywords | TSTypeOperators; +} + +export interface TSAsExpression extends BaseNode { + type: 'TSAsExpression'; + typeAnnotation: TSLiteralType | TSTypeKeywords | TSTypeOperators; + expression: Expressions | Identifier | JSXElement | Literals; +} + +export interface TSCallSignatureDeclaration extends BaseNode { + type: 'TSCallSignatureDeclaration'; + typeParameters?: TSTypeParameterDeclaration; + returnType?: TSTypeAnnotation; + params: Array; +} + +export interface TSClassImplements extends BaseNode { + type: 'TSClassImplements'; + typeParameters?: TSTypeParameterInstantiation; + expression: Identifier | MemberExpression; +} + +export interface TSConditionalType extends BaseNode { + type: 'TSConditionalType'; + trueType: TSLiteralType | TSTypeKeywords | TSTypeOperators; + falseType: TSLiteralType | TSTypeKeywords | TSTypeOperators; + extendsType: TSLiteralType | TSTypeKeywords | TSTypeOperators; + checkType: TSTypeKeywords | TSTypeOperators; +} + +export interface TSConstructSignatureDeclaration extends BaseNode { + type: 'TSConstructSignatureDeclaration'; + typeParameters?: TSTypeParameterDeclaration; + returnType?: TSTypeAnnotation; + params: Array; +} + +export interface TSConstructorType extends BaseNode { + type: 'TSConstructorType'; + typeParameters?: TSTypeParameterDeclaration; + returnType: TSTypeAnnotation; + params: Array; +} + +export interface TSDeclareFunction extends BaseNode { + type: 'TSDeclareFunction'; + generator: boolean; + expression: boolean; + declare?: boolean; + async: boolean; + typeParameters?: TSTypeParameterDeclaration; + returnType?: TSTypeAnnotation; + params: Array< + ArrayPattern | AssignmentPattern | Identifier | ObjectPattern | RestElement + >; + id: Identifier; + body?: BlockStatement; +} + +export interface TSEnumDeclaration extends BaseNode { + type: 'TSEnumDeclaration'; + declare?: boolean; + const?: boolean; + modifiers?: Array< + TSAsyncKeyword | TSPrivateKeyword | TSPublicKeyword | TSStaticKeyword + >; + members: Array; + id: Identifier; + decorators?: Array; +} + +export interface TSEnumMember extends BaseNode { + type: 'TSEnumMember'; + initializer?: Expressions | Identifier | Literal; + id: Identifier | Literal; +} + +export interface TSExportAssignment extends BaseNode { + type: 'TSExportAssignment'; + expression: Expressions | Identifier | Literal; +} + +export interface TSExternalModuleReference extends BaseNode { + type: 'TSExternalModuleReference'; + expression: Identifier | Literal; +} + +export interface TSFunctionType extends BaseNode { + type: 'TSFunctionType'; + typeParameters?: TSTypeParameterDeclaration; + returnType: TSTypeAnnotation; + params: Array< + | ArrayPattern + | AssignmentPattern + | Identifier + | ObjectPattern + | RestElement + | TSParameterProperty + >; +} + +export interface TSImportEqualsDeclaration extends BaseNode { + type: 'TSImportEqualsDeclaration'; + isExport: boolean; + moduleReference: Identifier | TSExternalModuleReference | TSQualifiedName; + id: Identifier; +} + +export interface TSImportType extends BaseNode { + type: 'TSImportType'; + isTypeOf: boolean; + typeParameters: null | TSTypeParameterInstantiation; + qualifier: null | Identifier; + parameter: TSLiteralType; +} + +export interface TSIndexSignature extends BaseNode { + type: 'TSIndexSignature'; + static?: boolean; + readonly?: boolean; + export?: boolean; + accessibility?: 'private' | 'public'; + typeAnnotation?: TSTypeAnnotation; + parameters: Array< + AssignmentPattern | Identifier | RestElement | TSParameterProperty + >; +} + +export interface TSIndexedAccessType extends BaseNode { + type: 'TSIndexedAccessType'; + objectType: TSTypeOperators | TSAnyKeyword; + indexType: TSLiteralType | TSTypeOperators | TSNeverKeyword; +} + +export interface TSInferType extends BaseNode { + type: 'TSInferType'; + typeParameter: TSTypeParameter; +} + +export interface TSInterfaceBody extends BaseNode { + type: 'TSInterfaceBody'; + body: Array; +} + +export interface TSInterfaceDeclaration extends BaseNode { + type: 'TSInterfaceDeclaration'; + declare?: boolean; + abstract?: boolean; + typeParameters?: TSTypeParameterDeclaration; + implements?: Array; + id: Identifier; + extends?: Array; + decorators?: Array; + body: TSInterfaceBody; +} + +export interface TSInterfaceHeritage extends BaseNode { + type: 'TSInterfaceHeritage'; + typeParameters?: TSTypeParameterInstantiation; + expression: Expressions | Identifier; +} + +export interface TSIntersectionType extends BaseNode { + type: 'TSIntersectionType'; + types: Array; +} + +export interface TSLiteralType extends BaseNode { + type: 'TSLiteralType'; + literal: Literals | UnaryExpression; +} + +export interface TSMappedType extends BaseNode { + type: 'TSMappedType'; + readonly?: boolean; + optional?: boolean | '-'; + typeParameter: TSTypeParameter; + typeAnnotation?: TSLiteralType | TSTypeKeywords | TSTypeOperators; +} + +export interface TSMethodSignature extends BaseNode { + type: 'TSMethodSignature'; + optional?: boolean; + computed: boolean; + typeParameters?: TSTypeParameterDeclaration; + returnType?: TSTypeAnnotation; + params: Array< + ArrayPattern | AssignmentPattern | Identifier | ObjectPattern | RestElement + >; + key: Expressions | Identifier | Literal; +} + +export interface TSModuleBlock extends BaseNode { + type: 'TSModuleBlock'; + body: Array; +} + +export interface TSModuleDeclaration extends BaseNode { + type: 'TSModuleDeclaration'; + global?: boolean; + declare?: boolean; + modifiers?: Array< + | TSAsyncKeyword + | TSPrivateKeyword + | TSProtectedKeyword + | TSPublicKeyword + | TSStaticKeyword + >; + id: Identifier | Literal; + body?: TSModuleBlock | TSModuleDeclaration; +} + +export interface TSNamespaceExportDeclaration extends BaseNode { + type: 'TSNamespaceExportDeclaration'; + id: Identifier; +} + +export interface TSNonNullExpression extends BaseNode { + type: 'TSNonNullExpression'; + expression: Expressions | Identifier | Literal; +} + +export interface TSOptionalType extends BaseNode { + type: 'TSOptionalType'; + typeAnnotation: TSStringKeyword; +} + +export interface TSParameterProperty extends BaseNode { + type: 'TSParameterProperty'; + static?: boolean; + readonly?: boolean; + export?: boolean; + accessibility?: 'private' | 'protected' | 'public'; + parameter: + | ArrayPattern + | AssignmentPattern + | Identifier + | ObjectPattern + | RestElement; + decorators?: Array; +} + +export interface TSParenthesizedType extends BaseNode { + type: 'TSParenthesizedType'; + typeAnnotation: TSLiteralType | TSTypeOperators; +} + +export interface TSPropertySignature extends BaseNode { + type: 'TSPropertySignature'; + readonly?: boolean; + optional?: boolean; + computed: boolean; + accessibility?: 'private' | 'protected' | 'public'; + typeAnnotation?: TSTypeAnnotation; + key: Expressions | Identifier | Literal; + initializer?: Literal; +} + +export interface TSQualifiedName extends BaseNode { + type: 'TSQualifiedName'; + right: Identifier; + left: Identifier | TSQualifiedName; +} + +export interface TSRestType extends BaseNode { + type: 'TSRestType'; + typeAnnotation: TSTypeOperators; +} + +export interface TSThisType extends BaseNode { + type: 'TSThisType'; +} + +export interface TSTupleType extends BaseNode { + type: 'TSTupleType'; + elementTypes: Array; +} + +export interface TSTypeAliasDeclaration extends BaseNode { + type: 'TSTypeAliasDeclaration'; + declare?: boolean; + typeParameters?: TSTypeParameterDeclaration; + typeAnnotation: TSLiteralType | TSThisType | TSTypeKeywords | TSTypeOperators; + id: Identifier; +} + +export interface TSTypeAnnotation extends BaseNode { + type: 'TSTypeAnnotation'; + typeAnnotation: TSLiteralType | TSThisType | TSTypeKeywords | TSTypeOperators; +} + +export interface TSTypeAssertion extends BaseNode { + type: 'TSTypeAssertion'; + typeAnnotation: TSTypeKeywords | TSTypeOperators; + expression: Expressions | Identifier | Literals; +} + +export interface TSTypeLiteral extends BaseNode { + type: 'TSTypeLiteral'; + members: Array; +} + +export interface TSTypeOperator extends BaseNode { + type: 'TSTypeOperator'; + operator: 'keyof' | 'unique'; + typeAnnotation: TSTypeKeywords | TSTypeOperators; +} + +export interface TSTypeParameter extends BaseNode { + type: 'TSTypeParameter'; + name: Identifier; + default?: TSLiteralType | TSTypeKeywords | TSTypeOperators; + constraint?: TSLiteralType | TSThisType | TSTypeKeywords | TSTypeOperators; +} + +export interface TSTypeParameterDeclaration extends BaseNode { + type: 'TSTypeParameterDeclaration'; + params: Array; +} + +export interface TSTypeParameterInstantiation extends BaseNode { + type: 'TSTypeParameterInstantiation'; + params: Array; +} + +export interface TSTypePredicate extends BaseNode { + type: 'TSTypePredicate'; + typeAnnotation: TSTypeAnnotation; + parameterName: Identifier | TSThisType; +} + +export interface TSTypeQuery extends BaseNode { + type: 'TSTypeQuery'; + exprName: Identifier | TSQualifiedName; +} + +export interface TSTypeReference extends BaseNode { + type: 'TSTypeReference'; + typeParameters?: TSTypeParameterInstantiation; + typeName: Identifier | TSQualifiedName; +} + +export interface TSUnionType extends BaseNode { + type: 'TSUnionType'; + types: Array; +} + +export interface TSAnyKeyword extends BaseNode { + type: 'TSAnyKeyword'; +} + +export interface TSAsyncKeyword extends BaseNode { + type: 'TSAsyncKeyword'; +} + +export interface TSBigIntKeyword extends BaseNode { + type: 'TSBigIntKeyword'; +} + +export interface TSBooleanKeyword extends BaseNode { + type: 'TSBooleanKeyword'; +} + +export interface TSNeverKeyword extends BaseNode { + type: 'TSNeverKeyword'; +} + +export interface TSNullKeyword extends BaseNode { + type: 'TSNullKeyword'; +} + +export interface TSNumberKeyword extends BaseNode { + type: 'TSNumberKeyword'; +} + +export interface TSObjectKeyword extends BaseNode { + type: 'TSObjectKeyword'; +} + +export interface TSPrivateKeyword extends BaseNode { + type: 'TSPrivateKeyword'; +} + +export interface TSProtectedKeyword extends BaseNode { + type: 'TSProtectedKeyword'; +} + +export interface TSPublicKeyword extends BaseNode { + type: 'TSPublicKeyword'; +} + +export interface TSStaticKeyword extends BaseNode { + type: 'TSStaticKeyword'; +} + +export interface TSStringKeyword extends BaseNode { + type: 'TSStringKeyword'; +} + +export interface TSSymbolKeyword extends BaseNode { + type: 'TSSymbolKeyword'; +} + +export interface TSUndefinedKeyword extends BaseNode { + type: 'TSUndefinedKeyword'; +} + +export interface TSUnknownKeyword extends BaseNode { + type: 'TSUnknownKeyword'; +} + +export interface TSVoidKeyword extends BaseNode { + type: 'TSVoidKeyword'; +} + +export type Declarations = + | ClassDeclaration + | ExportAllDeclaration + | ExportDefaultDeclaration + | ExportNamedDeclaration + | FunctionDeclaration + | ImportDeclaration + | VariableDeclaration + | TSDeclareFunction + | TSEnumDeclaration + | TSExportAssignment + | TSImportEqualsDeclaration + | TSInterfaceDeclaration + | TSModuleDeclaration + | TSTypeAliasDeclaration; + +export type Statements = + | ExpressionStatement + | BlockStatement + | EmptyStatement + | DebuggerStatement + | WithStatement + | ReturnStatement + | LabeledStatement + | BreakStatement + | ContinueStatement + | IfStatement + | SwitchStatement + | ThrowStatement + | TryStatement + | WhileStatement + | DoWhileStatement + | ForStatement + | ForInStatement + | ForOfStatement; + +export type Literals = TemplateLiteral | Literal | BigIntLiteral; + +export type Expressions = + | ThisExpression + | ArrayExpression + | ObjectExpression + | FunctionExpression + | ArrowFunctionExpression + | YieldExpression + | UnaryExpression + | UpdateExpression + | BinaryExpression + | AssignmentExpression + | LogicalExpression + | MemberExpression + | ConditionalExpression + | CallExpression + | NewExpression + | SequenceExpression + | TaggedTemplateExpression + | ClassExpression + | MetaProperty + | AwaitExpression + | TSAsExpression + | TSNonNullExpression + | TSTypeAssertion; + +export type TSSignatures = + | TSCallSignatureDeclaration + | TSConstructSignatureDeclaration + | TSIndexSignature + | TSMethodSignature + | TSPropertySignature; + +export type TSTypeKeywords = + | TSAnyKeyword + | TSBigIntKeyword + | TSBooleanKeyword + | TSNeverKeyword + | TSNullKeyword + | TSNumberKeyword + | TSObjectKeyword + | TSStringKeyword + | TSSymbolKeyword + | TSUndefinedKeyword + | TSUnknownKeyword + | TSVoidKeyword; + +export type TSTypeOperators = + | TSArrayType + | TSConditionalType + | TSConstructorType + | TSFunctionType + | TSImportType + | TSIndexedAccessType + | TSInferType + | TSIntersectionType + | TSMappedType + | TSParenthesizedType + | TSTupleType + | TSTypeLiteral + | TSTypeOperator + | TSTypePredicate + | TSTypeQuery + | TSTypeReference + | TSUnionType + | TSOptionalType + | TSRestType; From 1e78ac5a712a4c943184726503e1afe0699bda3f Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Fri, 25 Jan 2019 22:12:54 -0800 Subject: [PATCH 13/92] more types --- packages/typescript-estree/src/convert.ts | 11 +- .../typescript-estree/src/es-tree-nodes.ts | 1 + packages/typescript-estree/src/typedefs.ts | 444 ++++++++++++++++-- 3 files changed, 410 insertions(+), 46 deletions(-) diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 48e92a8d545f..712d340421c6 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -1631,20 +1631,19 @@ export default function convert(config: ConvertConfig): ESTreeNode | null { if (isJSXToken(parent!)) { const jsxMemberExpression = { type: AST_NODE_TYPES.MemberExpression, - object: convertChild(node.expression), - property: convertChild(node.name) + object: convertChild(node.expression)!, + property: convertChild(node.name)! }; const isNestedMemberExpression = node.expression.kind === SyntaxKind.PropertyAccessExpression; if (node.expression.kind === SyntaxKind.ThisKeyword) { - (jsxMemberExpression as any).object.name = 'this'; + (jsxMemberExpression.object as any).name = 'this'; } - (jsxMemberExpression as any).object.type = isNestedMemberExpression + jsxMemberExpression.object.type = isNestedMemberExpression ? AST_NODE_TYPES.MemberExpression : AST_NODE_TYPES.JSXIdentifier; - (jsxMemberExpression as any).property.type = - AST_NODE_TYPES.JSXIdentifier; + jsxMemberExpression.property.type = AST_NODE_TYPES.JSXIdentifier; Object.assign(result, jsxMemberExpression); } else { Object.assign(result, { diff --git a/packages/typescript-estree/src/es-tree-nodes.ts b/packages/typescript-estree/src/es-tree-nodes.ts index 5dffb31f744a..c0f68cb45d82 100644 --- a/packages/typescript-estree/src/es-tree-nodes.ts +++ b/packages/typescript-estree/src/es-tree-nodes.ts @@ -2,6 +2,7 @@ * @fileoverview Definition of AST structure. * @author Armano */ +/* eslint-disable @typescript-eslint/array-type */ export interface Position { line: number; diff --git a/packages/typescript-estree/src/typedefs.ts b/packages/typescript-estree/src/typedefs.ts index 0434ef62ab3c..a305eb8a98ec 100644 --- a/packages/typescript-estree/src/typedefs.ts +++ b/packages/typescript-estree/src/typedefs.ts @@ -37,15 +37,58 @@ interface NodeBase { // source?: string | null; } -// NOTE - got to line 860 +//////////////// NOTE - got to line 1838 //////////////////// // ensure you sort the union members alphabetically... type ESTreeNode = null; +////////// +// Reusable Unions +// These are based off of types used in the Typescript AST definitions +////////// + +type Accessibility = 'public' | 'protected' | 'private'; type BindingPattern = ArrayPattern | ObjectPattern; -type BindingName = Identifier | BindingPattern; +type BindingName = BindingPattern | Identifier; +type ClassElement = + | ClassProperty + | FunctionExpression + | MethodDefinition + | TSAbstractClassProperty + | TSAbstractMethodDefinition + | TSIndexSignature; type Expression = null; // TODO - get lists from ts source and convert to estree nodes +type ExpressionWithTypeArguments = TSClassImplements | TSInterfaceHeritage; type ForInitialiser = Expression | VariableDeclaration; +type ImportClause = + | ImportDefaultSpecifier + | ImportNamespaceSpecifier + | ImportSpecifier; +type JSXChild = JSXElement | JSXExpression | JSXFragment | JSXText; +type JSXExpression = + | JSXEmptyExpression + | JSXSpreadChild + | JSXExpressionContainer; +type LeftHandSideExpression = + | ArrayExpression + | ArrayPattern + | BigIntLiteral + | CallExpression + | ClassExpression + | ClassDeclaration + | Expression + | FunctionExpression + | Import + | Literal + | MemberExpression + | ObjectExpression + | ObjectPattern + | Super + | TaggedTemplateExpression + | TemplateLiteral + | ThisExpression + | TSNonNullExpression + | TSNullKeyword; type ObjectLiteralElementLike = | MethodDefinition | Property @@ -55,8 +98,94 @@ type ObjectLiteralElementLike = type Parameter = AssignmentPattern | RestElement | TSParameterProperty; type PropertyName = Identifier | Literal; type Statement = null; // TODO - get lists from ts source and convert to estree nodes +type TSUnaryExpression = + | AwaitExpression + | LeftHandSideExpression + | TSTypeAssertion + | UnaryExpression + | UpdateExpression; + +/////////////// +// Base, common types +/////////////// + +interface BinaryExpressionBase extends NodeBase { + operator: string; + left: Expression; + right: Expression; +} + +interface ClassDeclarationBase extends NodeBase { + typeParameters: TSTypeParameterDeclaration; + superTypeParameters: TSTypeParameterDeclaration; + id: Identifier | undefined; + body: ClassBody; + superClass: LeftHandSideExpression | undefined; + implements: ExpressionWithTypeArguments[]; + abstract?: boolean; + declare?: boolean; + decorators?: Decorator[]; +} -// ensure you sort the following interfaces alphabetically +interface ClassPropertyBase extends NodeBase { + key: PropertyName; + value: Expression; + computed: boolean; + static: boolean; + readonly: boolean | undefined; + decorators?: Decorator[]; + accessibility?: Accessibility; + optional?: boolean; + definite?: boolean; + typeAnnotation?: TSTypeAnnotation; +} + +interface FunctionDeclarationBase extends NodeBase { + type: 'FunctionDeclaration'; + id: Identifier | null; + generator: boolean; + expression: false; + async: boolean; + params: Parameter[]; + body: BlockStatement | null | undefined; + returnType?: TSTypeAnnotation; + typeParameters?: TSTypeParameterDeclaration; +} + +interface LiteralBase extends NodeBase { + raw: boolean | number | RegExp | string | null; + value: string; + regex?: { + pattern: string; + flags: string; + }; +} + +interface MethodDefinitionBase extends NodeBase { + key: PropertyName; + value: FunctionExpression; + computed: boolean; + static: boolean; + kind: 'method' | 'get' | 'set' | 'constructor'; + decorators?: Decorator[]; + accessibility?: Accessibility; + typeParameters?: TSTypeParameterDeclaration; +} + +interface TSHeritageBase extends NodeBase { + expression: Expression; + typeParameters?: TSTypeParameterDeclaration; +} + +interface UnaryExpressionBase extends NodeBase { + operator: string; + prefix: boolean; + argument: LeftHandSideExpression | Literal | UnaryExpression; +} + +/////////////// +// Typescript ESTree Nodes +/////////////// interface ArrayExpression extends NodeBase { type: 'ArrayExpression'; @@ -66,6 +195,45 @@ interface ArrayExpression extends NodeBase { interface ArrayPattern extends NodeBase { type: 'ArrayPattern'; elements: Expression[]; + typeAnnotation?: TSTypeAnnotation; + optional?: boolean; +} + +interface ArrowFunctionExpression extends NodeBase { + type: 'ArrowFunctionExpression'; + generator: false; + id: null; + params: Parameter[]; + body: Expression | BlockStatement; + async: boolean; + expression: boolean; + returnType: TSTypeAnnotation; + typeParameters: TSTypeParameterDeclaration; +} + +interface AssignmentExpression extends BinaryExpressionBase { + type: 'AssignmentExpression'; +} + +interface AssignmentPattern extends NodeBase { + type: 'AssignmentPattern'; + left: BindingName; + right?: Expression; + typeAnnotation?: TSTypeAnnotation; + optional?: boolean; +} + +interface AwaitExpression extends NodeBase { + type: 'AwaitExpression'; + argument: TSUnaryExpression; +} + +interface BigIntLiteral extends LiteralBase { + type: 'BigIntLiteral'; +} + +interface BinaryExpression extends BinaryExpressionBase { + type: 'BinaryExpression'; } interface BlockStatement extends NodeBase { @@ -78,24 +246,41 @@ interface BreakStatement extends NodeBase { label: Identifier | null; } +interface CallExpression extends NodeBase { + type: 'CallExpression'; + callee: LeftHandSideExpression; + arguments: Expression[]; + typeParameters?: TSTypeParameterDeclaration; +} + interface CatchClause extends NodeBase { type: 'CatchClause'; param: BindingName | null; body: BlockStatement; } -interface ClassProperty extends NodeBase { +interface ClassBody extends NodeBase { + type: 'ClassBody'; + body: ClassElement[]; +} + +interface ClassDeclaration extends ClassDeclarationBase { + type: 'ClassDeclaration'; +} + +interface ClassExpression extends ClassDeclarationBase { + type: 'ClassExpression'; +} + +interface ClassProperty extends ClassPropertyBase { type: 'ClassProperty'; - key: PropertyName; - value: Expression; - computed: boolean; - static: boolean; - readonly: boolean | undefined; - decorators?: Decorator[]; - accessibility?: 'public' | 'protected' | 'private'; - optional?: boolean; - definite?: boolean; - typeAnnotation?: TSTypeAnnotation; +} + +interface ConditionalExpression extends NodeBase { + type: 'ConditionalExpression'; + test: Expression; + consequent: Expression; + alternate: Expression; } interface ContinueStatement extends NodeBase { @@ -103,23 +288,46 @@ interface ContinueStatement extends NodeBase { label: Identifier | null; } +interface DebuggerStatement extends NodeBase { + type: 'DebuggerStatement'; +} + +interface Decorator extends NodeBase { + type: 'Decorator'; + expression: LeftHandSideExpression; +} + interface DoWhileStatement extends NodeBase { type: 'DoWhileStatement'; test: Expression; body: Statement; } +interface EmptyStatement extends NodeBase { + type: 'EmptyStatement'; +} + +interface ExportAllDeclaration extends NodeBase { + type: 'ExportAllDeclaration'; + source: Expression | null; +} + interface ExportDefaultDeclaration extends NodeBase { type: 'ExportDefaultDeclaration'; - declaration: Node; + declaration: Expression; } interface ExportNamedDeclaration extends NodeBase { type: 'ExportNamedDeclaration'; - declaration: Node; - // we don't put anything in these? - specifiers: never[]; - source: null; + declaration: Expression | null; + specifiers: ExportSpecifier[]; + source: Expression | null; +} + +interface ExportSpecifier extends NodeBase { + type: 'ExportSpecifier'; + local: Identifier; + exported: Identifier; } interface ExpressionStatement extends NodeBase { @@ -150,22 +358,19 @@ interface ForStatement extends NodeBase { body: Statement; } -interface FunctionDeclaration extends NodeBase { +interface FunctionDeclaration extends FunctionDeclarationBase { type: 'FunctionDeclaration'; - id: Identifier | null; - generator: boolean; - expression: false; - async: boolean; - params: Parameter; - body: BlockStatement | null | undefined; - returnType?: TSTypeAnnotation; - typeParameters?: TSTypeParameterDeclaration; +} + +interface FunctionExpression extends FunctionDeclarationBase { + type: 'FunctionExpression'; } interface Identifier extends NodeBase { type: 'Identifier'; name: string; typeAnnotation?: TSTypeAnnotation; + optional?: boolean; } interface IfStatement extends NodeBase { @@ -175,12 +380,76 @@ interface IfStatement extends NodeBase { alternate: Statement | null; } +interface Import extends NodeBase { + type: 'Import'; +} + +interface ImportDeclaration extends NodeBase { + type: 'ImportDeclaration'; + source: Expression; + specifiers: ImportClause[]; +} + +interface ImportDefaultSpecifier extends NodeBase { + type: 'ImportDefaultSpecifier'; + local: Identifier; +} + +interface ImportNamespaceSpecifier extends NodeBase { + type: 'ImportNamespaceSpecifier'; + local: Identifier; +} + +interface JSXElement extends NodeBase { + type: 'JSXElement'; + openingElement: JSXOpeningElement; + closingElement: JSXClosingElement; + children: JSXChild[]; +} + +interface JSXIdentifier extends NodeBase { + type: 'JSXIdentifier'; + name: string; +} + interface LabeledStatement extends NodeBase { type: 'LabeledStatement'; label: Identifier; body: Statement; } +interface Literal extends LiteralBase { + type: 'Literal'; +} + +interface LogicalExpression extends BinaryExpressionBase { + type: 'LogicalExpression'; +} + +interface MemberExpression extends NodeBase { + type: 'MemberExpression'; + object: LeftHandSideExpression; + property: Expression | Identifier; + computed?: boolean; +} + +interface MetaProperty extends NodeBase { + type: 'MetaProperty'; + meta: Identifier; + property: Identifier; +} + +interface MethodDefinition extends MethodDefinitionBase { + type: 'MethodDefinition'; +} + +interface NewExpression extends NodeBase { + type: 'NewExpression'; + callee: LeftHandSideExpression; + arguments: Expression[]; + typeParameters?: TSTypeParameterDeclaration; +} + interface ObjectExpression extends NodeBase { type: 'ObjectExpression'; properties: ObjectLiteralElementLike[]; @@ -189,6 +458,8 @@ interface ObjectExpression extends NodeBase { interface ObjectPattern extends NodeBase { type: 'ObjectPattern'; properties: ObjectLiteralElementLike[]; + typeAnnotation?: TSTypeAnnotation; + optional?: boolean; } interface Program extends NodeBase { @@ -200,18 +471,39 @@ interface Program extends NodeBase { interface Property extends NodeBase { type: 'Property'; key: PropertyName; - value: Expression | AssignmentPattern; // TODO + value: Expression | AssignmentPattern | BindingName; // TODO computed: boolean; method: boolean; shorthand: boolean; kind: 'init'; } +interface RestElement extends NodeBase { + type: 'RestElement'; + argument: BindingName | Expression | PropertyName; + typeAnnotation?: TSTypeAnnotation; + optional?: boolean; +} + interface ReturnStatement extends NodeBase { type: 'ReturnStatement'; argument: Expression | null; } +interface SequenceExpression extends NodeBase { + type: 'SequenceExpression'; + expressions: Expression[]; +} + +interface SpreadElement extends NodeBase { + type: 'SpreadElement'; + argument: BindingName | Expression | PropertyName; +} + +interface Super extends NodeBase { + type: 'Super'; +} + interface SwitchCase extends NodeBase { type: 'SwitchCase'; test: Expression; @@ -224,6 +516,28 @@ interface SwitchStatement extends NodeBase { cases: SwitchCase[]; } +interface TaggedTemplateExpression extends NodeBase { + type: 'TaggedTemplateExpression'; + typeParameters: TSTypeParameterDeclaration; + tag: LeftHandSideExpression; + quasi: TemplateLiteral; +} + +interface TemplateElement extends NodeBase { + type: 'TemplateElement'; + value: { + raw: string; + cooked: string; + }; + tail: boolean; +} + +interface TemplateLiteral extends NodeBase { + type: 'TemplateLiteral'; + quasis: TemplateElement[]; + expressions: Expression[]; +} + interface ThrowStatement extends NodeBase { type: 'ThrowStatement'; argument: Statement | null; @@ -236,18 +550,16 @@ interface TryStatement extends NodeBase { finalizer: BlockStatement; } -interface TSAbstractClassProperty extends NodeBase { +interface TSAbstractClassProperty extends ClassPropertyBase { type: 'TSAbstractClassProperty'; - key: PropertyName; - value: Expression; - computed: boolean; - static: boolean; - readonly: boolean | undefined; - decorators?: Decorator[]; - accessibility?: 'public' | 'protected' | 'private'; - optional?: boolean; - definite?: boolean; - typeAnnotation?: TSTypeAnnotation; +} + +interface TSAbstractMethodDefinition extends MethodDefinitionBase { + type: 'TSAbstractMethodDefinition'; +} + +interface TSClassImplements extends TSHeritageBase { + type: 'TSClassImplements'; } interface TSDeclareFunction extends NodeBase { @@ -263,6 +575,52 @@ interface TSDeclareFunction extends NodeBase { typeParameters?: TSTypeParameterDeclaration; } +interface TSExportAssignment extends NodeBase { + type: 'TSExportAssignment'; + expression: Expression; +} + +interface TSInterfaceHeritage extends TSHeritageBase { + type: 'TSInterfaceHeritage'; +} + +interface TSModuleBlock extends NodeBase { + type: 'TSModuleBlock'; + body: Statement[]; +} + +interface TSNullKeyword extends NodeBase { + type: 'TSNullKeyword'; +} + +interface TSParameterProperty extends NodeBase { + type: 'TSParameterProperty'; + accessibility: Accessibility | undefined; + readonly: boolean | undefined; + static: boolean | undefined; + export: boolean | undefined; + parameter: AssignmentPattern | BindingName | RestElement; +} + +interface TSTypeOperator extends NodeBase { + type: 'TSTypeOperator'; + operator: 'keyof' | 'unique'; + typeAnnotation?: TSTypeAnnotation; +} + +interface TSTypeParameterDeclaration extends NodeBase { + type: 'TSTypeParameterDeclaration'; + params: TSTypeParameter[]; +} + +interface UpdateExpression extends UnaryExpressionBase { + type: 'UpdateExpression'; +} + +interface UnaryExpression extends UnaryExpressionBase { + type: 'UnaryExpression'; +} + interface VariableDeclaration extends NodeBase { type: 'VariableDeclaration'; declarations: VariableDeclarator[]; @@ -288,3 +646,9 @@ interface WithStatement extends NodeBase { object: Expression; body: Statement; } + +interface YieldExpression extends NodeBase { + type: 'YieldExpression'; + delegate: boolean; + argument?: Expression; +} From f5d15fa220f3808be26e4652bee2c1eef07b6cc9 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Wed, 30 Jan 2019 11:16:04 -0800 Subject: [PATCH 14/92] Finished adding types --- packages/typescript-estree/src/typedefs.ts | 667 ++++++++++++++++++--- 1 file changed, 572 insertions(+), 95 deletions(-) diff --git a/packages/typescript-estree/src/typedefs.ts b/packages/typescript-estree/src/typedefs.ts index a305eb8a98ec..77ec380030f8 100644 --- a/packages/typescript-estree/src/typedefs.ts +++ b/packages/typescript-estree/src/typedefs.ts @@ -40,7 +40,7 @@ interface NodeBase { //////////////// NOTE - got to line 1838 //////////////////// // ensure you sort the union members alphabetically... -type ESTreeNode = null; +export type Node = null; // TODO ////////// // Reusable Unions @@ -57,6 +57,7 @@ type ClassElement = | TSAbstractClassProperty | TSAbstractMethodDefinition | TSIndexSignature; +type EntityName = Identifier | TSQualifiedName; type Expression = null; // TODO - get lists from ts source and convert to estree nodes type ExpressionWithTypeArguments = TSClassImplements | TSInterfaceHeritage; type ForInitialiser = Expression | VariableDeclaration; @@ -69,26 +70,38 @@ type JSXExpression = | JSXEmptyExpression | JSXSpreadChild | JSXExpressionContainer; +type JSXTagNameExpression = Identifier | MemberExpression | ThisExpression; type LeftHandSideExpression = | ArrayExpression | ArrayPattern - | BigIntLiteral | CallExpression | ClassExpression | ClassDeclaration | Expression | FunctionExpression | Import - | Literal + | LiteralExpression | MemberExpression | ObjectExpression | ObjectPattern | Super | TaggedTemplateExpression - | TemplateLiteral | ThisExpression | TSNonNullExpression | TSNullKeyword; +type LiteralExpression = BigIntLiteral | Literal | TemplateLiteral; +type Modifier = + | TSAbstractKeyword + | TSAsyncKeyword + | TSConstKeyword + | TSDeclareKeyword + | TSDefaultKeyword + | TSExportKeyword + | TSPublicKeyword + | TSPrivateKeyword + | TSProtectedKeyword + | TSReadonlyKeyword + | TSStaticKeyword; type ObjectLiteralElementLike = | MethodDefinition | Property @@ -98,6 +111,49 @@ type ObjectLiteralElementLike = type Parameter = AssignmentPattern | RestElement | TSParameterProperty; type PropertyName = Identifier | Literal; type Statement = null; // TODO - get lists from ts source and convert to estree nodes +type TypeElement = + | TSCallSignatureDeclaration + | TSConstructSignatureDeclaration + | TSIndexSignature + | TSMethodSignature + | TSPropertySignature; +type TypeNode = + | ThisExpression + | TSAnyKeyword + | TSArrayType + | TSBigIntKeyword + | TSBooleanKeyword + | TSClassImplements + | TSConditionalType + | TSConstructorType + | TSFunctionType + | TSImportType + | TSIndexedAccessType + | TSInferType + | TSInterfaceHeritage + | TSIntersectionType + | TSLiteralType + | TSMappedType + | TSNeverKeyword + | TSNullKeyword + | TSNumberKeyword + | TSObjectKeyword + | TSOptionalType + | TSParenthesizedType + | TSRestType + | TSStringKeyword + | TSSymbolKeyword + | TSThisType + | TSTupleType + | TSTypeLiteral + | TSTypeOperator + | TSTypeReference + | TSTypePredicate + | TSTypeQuery + | TSUndefinedKeyword + | TSUnionType + | TSUnknownKeyword + | TSVoidKeyword; type TSUnaryExpression = | AwaitExpression | LeftHandSideExpression @@ -117,7 +173,7 @@ interface BinaryExpressionBase extends NodeBase { interface ClassDeclarationBase extends NodeBase { typeParameters: TSTypeParameterDeclaration; - superTypeParameters: TSTypeParameterDeclaration; + superTypeParameters: TSTypeParameterInstantiation; id: Identifier | undefined; body: ClassBody; superClass: LeftHandSideExpression | undefined; @@ -141,10 +197,9 @@ interface ClassPropertyBase extends NodeBase { } interface FunctionDeclarationBase extends NodeBase { - type: 'FunctionDeclaration'; id: Identifier | null; generator: boolean; - expression: false; + expression: boolean; async: boolean; params: Parameter[]; body: BlockStatement | null | undefined; @@ -152,6 +207,12 @@ interface FunctionDeclarationBase extends NodeBase { typeParameters?: TSTypeParameterDeclaration; } +interface FunctionSignatureBase extends NodeBase { + params: Parameter[]; + returnType?: TSTypeAnnotation; + typeParameters?: TSTypeParameterDeclaration; +} + interface LiteralBase extends NodeBase { raw: boolean | number | RegExp | string | null; value: string; @@ -187,21 +248,21 @@ interface UnaryExpressionBase extends NodeBase { // Typescript ESTree Nodes /////////////// -interface ArrayExpression extends NodeBase { +export interface ArrayExpression extends NodeBase { type: 'ArrayExpression'; elements: Expression[]; } -interface ArrayPattern extends NodeBase { +export interface ArrayPattern extends NodeBase { type: 'ArrayPattern'; elements: Expression[]; typeAnnotation?: TSTypeAnnotation; optional?: boolean; } -interface ArrowFunctionExpression extends NodeBase { +export interface ArrowFunctionExpression extends NodeBase { type: 'ArrowFunctionExpression'; - generator: false; + generator: boolean; id: null; params: Parameter[]; body: Expression | BlockStatement; @@ -211,11 +272,11 @@ interface ArrowFunctionExpression extends NodeBase { typeParameters: TSTypeParameterDeclaration; } -interface AssignmentExpression extends BinaryExpressionBase { +export interface AssignmentExpression extends BinaryExpressionBase { type: 'AssignmentExpression'; } -interface AssignmentPattern extends NodeBase { +export interface AssignmentPattern extends NodeBase { type: 'AssignmentPattern'; left: BindingName; right?: Expression; @@ -223,126 +284,126 @@ interface AssignmentPattern extends NodeBase { optional?: boolean; } -interface AwaitExpression extends NodeBase { +export interface AwaitExpression extends NodeBase { type: 'AwaitExpression'; argument: TSUnaryExpression; } -interface BigIntLiteral extends LiteralBase { +export interface BigIntLiteral extends LiteralBase { type: 'BigIntLiteral'; } -interface BinaryExpression extends BinaryExpressionBase { +export interface BinaryExpression extends BinaryExpressionBase { type: 'BinaryExpression'; } -interface BlockStatement extends NodeBase { +export interface BlockStatement extends NodeBase { type: 'BlockStatement'; body: Statement[]; } -interface BreakStatement extends NodeBase { +export interface BreakStatement extends NodeBase { type: 'BreakStatement'; label: Identifier | null; } -interface CallExpression extends NodeBase { +export interface CallExpression extends NodeBase { type: 'CallExpression'; callee: LeftHandSideExpression; arguments: Expression[]; - typeParameters?: TSTypeParameterDeclaration; + typeParameters?: TSTypeParameterInstantiation; } -interface CatchClause extends NodeBase { +export interface CatchClause extends NodeBase { type: 'CatchClause'; param: BindingName | null; body: BlockStatement; } -interface ClassBody extends NodeBase { +export interface ClassBody extends NodeBase { type: 'ClassBody'; body: ClassElement[]; } -interface ClassDeclaration extends ClassDeclarationBase { +export interface ClassDeclaration extends ClassDeclarationBase { type: 'ClassDeclaration'; } -interface ClassExpression extends ClassDeclarationBase { +export interface ClassExpression extends ClassDeclarationBase { type: 'ClassExpression'; } -interface ClassProperty extends ClassPropertyBase { +export interface ClassProperty extends ClassPropertyBase { type: 'ClassProperty'; } -interface ConditionalExpression extends NodeBase { +export interface ConditionalExpression extends NodeBase { type: 'ConditionalExpression'; test: Expression; consequent: Expression; alternate: Expression; } -interface ContinueStatement extends NodeBase { +export interface ContinueStatement extends NodeBase { type: 'ContinueStatement'; label: Identifier | null; } -interface DebuggerStatement extends NodeBase { +export interface DebuggerStatement extends NodeBase { type: 'DebuggerStatement'; } -interface Decorator extends NodeBase { +export interface Decorator extends NodeBase { type: 'Decorator'; expression: LeftHandSideExpression; } -interface DoWhileStatement extends NodeBase { +export interface DoWhileStatement extends NodeBase { type: 'DoWhileStatement'; test: Expression; body: Statement; } -interface EmptyStatement extends NodeBase { +export interface EmptyStatement extends NodeBase { type: 'EmptyStatement'; } -interface ExportAllDeclaration extends NodeBase { +export interface ExportAllDeclaration extends NodeBase { type: 'ExportAllDeclaration'; source: Expression | null; } -interface ExportDefaultDeclaration extends NodeBase { +export interface ExportDefaultDeclaration extends NodeBase { type: 'ExportDefaultDeclaration'; declaration: Expression; } -interface ExportNamedDeclaration extends NodeBase { +export interface ExportNamedDeclaration extends NodeBase { type: 'ExportNamedDeclaration'; declaration: Expression | null; specifiers: ExportSpecifier[]; source: Expression | null; } -interface ExportSpecifier extends NodeBase { +export interface ExportSpecifier extends NodeBase { type: 'ExportSpecifier'; local: Identifier; exported: Identifier; } -interface ExpressionStatement extends NodeBase { +export interface ExpressionStatement extends NodeBase { type: 'ExpressionStatement'; expression: Expression; } -interface ForInStatement extends NodeBase { +export interface ForInStatement extends NodeBase { type: 'ForInStatement'; left: ForInitialiser; right: Expression; body: Statement; } -interface ForOfStatement extends NodeBase { +export interface ForOfStatement extends NodeBase { type: 'ForOfStatement'; left: ForInitialiser; right: Expression; @@ -350,7 +411,7 @@ interface ForOfStatement extends NodeBase { await: boolean; } -interface ForStatement extends NodeBase { +export interface ForStatement extends NodeBase { type: 'ForStatement'; init: Expression | ForInitialiser | null; test: Expression | null; @@ -358,117 +419,182 @@ interface ForStatement extends NodeBase { body: Statement; } -interface FunctionDeclaration extends FunctionDeclarationBase { +export interface FunctionDeclaration extends FunctionDeclarationBase { type: 'FunctionDeclaration'; } -interface FunctionExpression extends FunctionDeclarationBase { +export interface FunctionExpression extends FunctionDeclarationBase { type: 'FunctionExpression'; } -interface Identifier extends NodeBase { +export interface Identifier extends NodeBase { type: 'Identifier'; name: string; typeAnnotation?: TSTypeAnnotation; optional?: boolean; } -interface IfStatement extends NodeBase { +export interface IfStatement extends NodeBase { type: 'IfStatement'; test: Expression; consequent: Statement; alternate: Statement | null; } -interface Import extends NodeBase { +export interface Import extends NodeBase { type: 'Import'; } -interface ImportDeclaration extends NodeBase { +export interface ImportDeclaration extends NodeBase { type: 'ImportDeclaration'; source: Expression; specifiers: ImportClause[]; } -interface ImportDefaultSpecifier extends NodeBase { +export interface ImportDefaultSpecifier extends NodeBase { type: 'ImportDefaultSpecifier'; local: Identifier; } -interface ImportNamespaceSpecifier extends NodeBase { +export interface ImportNamespaceSpecifier extends NodeBase { type: 'ImportNamespaceSpecifier'; local: Identifier; } -interface JSXElement extends NodeBase { +export interface ImportSpecifier extends NodeBase { + type: 'ImportSpecifier'; + local: Identifier; + imported: Identifier; +} + +export interface JSXAttribute extends NodeBase { + type: 'JSXAttribute'; + name: JSXIdentifier; + value: Literal | JSXExpression | null; +} + +export interface JSXClosingElement extends NodeBase { + type: 'JSXClosingElement'; + name: JSXTagNameExpression; +} + +export interface JSXClosingFragment extends NodeBase { + type: 'JSXClosingFragment'; +} + +export interface JSXElement extends NodeBase { type: 'JSXElement'; openingElement: JSXOpeningElement; - closingElement: JSXClosingElement; + closingElement: JSXClosingElement | null; + children: JSXChild[]; +} + +export interface JSXEmptyExpression extends NodeBase { + type: 'JSXEmptyExpression'; +} + +export interface JSXExpressionContainer extends NodeBase { + type: 'JSXExpressionContainer'; + expression: Expression | JSXEmptyExpression; +} + +export interface JSXFragment extends NodeBase { + type: 'JSXFragment'; + openingFragment: JSXOpeningFragment; + closingFragment: JSXClosingFragment; children: JSXChild[]; } -interface JSXIdentifier extends NodeBase { +export interface JSXIdentifier extends NodeBase { type: 'JSXIdentifier'; name: string; } -interface LabeledStatement extends NodeBase { +export interface JSXOpeningElement extends NodeBase { + type: 'JSXOpeningElement'; + typeParameters: TSTypeParameterInstantiation | undefined; + selfClosing: boolean; + name: JSXTagNameExpression; + attributes: JSXAttribute[]; +} + +export interface JSXOpeningFragment extends NodeBase { + type: 'JSXOpeningFragment'; +} + +export interface JSXSpreadAttribute extends NodeBase { + type: 'JSXSpreadAttribute'; + argument: Expression; +} + +export interface JSXSpreadChild extends NodeBase { + type: 'JSXSpreadChild'; + expression: Expression | JSXEmptyExpression; +} + +export interface JSXText extends NodeBase { + type: 'JSXText'; + value: string; + raw: string; +} + +export interface LabeledStatement extends NodeBase { type: 'LabeledStatement'; label: Identifier; body: Statement; } -interface Literal extends LiteralBase { +export interface Literal extends LiteralBase { type: 'Literal'; } -interface LogicalExpression extends BinaryExpressionBase { +export interface LogicalExpression extends BinaryExpressionBase { type: 'LogicalExpression'; } -interface MemberExpression extends NodeBase { +export interface MemberExpression extends NodeBase { type: 'MemberExpression'; object: LeftHandSideExpression; property: Expression | Identifier; computed?: boolean; } -interface MetaProperty extends NodeBase { +export interface MetaProperty extends NodeBase { type: 'MetaProperty'; meta: Identifier; property: Identifier; } -interface MethodDefinition extends MethodDefinitionBase { +export interface MethodDefinition extends MethodDefinitionBase { type: 'MethodDefinition'; } -interface NewExpression extends NodeBase { +export interface NewExpression extends NodeBase { type: 'NewExpression'; callee: LeftHandSideExpression; arguments: Expression[]; - typeParameters?: TSTypeParameterDeclaration; + typeParameters?: TSTypeParameterInstantiation; } -interface ObjectExpression extends NodeBase { +export interface ObjectExpression extends NodeBase { type: 'ObjectExpression'; properties: ObjectLiteralElementLike[]; } -interface ObjectPattern extends NodeBase { +export interface ObjectPattern extends NodeBase { type: 'ObjectPattern'; properties: ObjectLiteralElementLike[]; typeAnnotation?: TSTypeAnnotation; optional?: boolean; } -interface Program extends NodeBase { +export interface Program extends NodeBase { type: 'Program'; body: Statement[]; sourceType: 'module' | 'script'; } -interface Property extends NodeBase { +export interface Property extends NodeBase { type: 'Property'; key: PropertyName; value: Expression | AssignmentPattern | BindingName; // TODO @@ -478,52 +604,52 @@ interface Property extends NodeBase { kind: 'init'; } -interface RestElement extends NodeBase { +export interface RestElement extends NodeBase { type: 'RestElement'; argument: BindingName | Expression | PropertyName; typeAnnotation?: TSTypeAnnotation; optional?: boolean; } -interface ReturnStatement extends NodeBase { +export interface ReturnStatement extends NodeBase { type: 'ReturnStatement'; argument: Expression | null; } -interface SequenceExpression extends NodeBase { +export interface SequenceExpression extends NodeBase { type: 'SequenceExpression'; expressions: Expression[]; } -interface SpreadElement extends NodeBase { +export interface SpreadElement extends NodeBase { type: 'SpreadElement'; argument: BindingName | Expression | PropertyName; } -interface Super extends NodeBase { +export interface Super extends NodeBase { type: 'Super'; } -interface SwitchCase extends NodeBase { +export interface SwitchCase extends NodeBase { type: 'SwitchCase'; test: Expression; consequent: Statement[]; } -interface SwitchStatement extends NodeBase { +export interface SwitchStatement extends NodeBase { type: 'SwitchStatement'; discriminant: Expression; cases: SwitchCase[]; } -interface TaggedTemplateExpression extends NodeBase { +export interface TaggedTemplateExpression extends NodeBase { type: 'TaggedTemplateExpression'; - typeParameters: TSTypeParameterDeclaration; + typeParameters: TSTypeParameterInstantiation; tag: LeftHandSideExpression; quasi: TemplateLiteral; } -interface TemplateElement extends NodeBase { +export interface TemplateElement extends NodeBase { type: 'TemplateElement'; value: { raw: string; @@ -532,68 +658,283 @@ interface TemplateElement extends NodeBase { tail: boolean; } -interface TemplateLiteral extends NodeBase { +export interface TemplateLiteral extends NodeBase { type: 'TemplateLiteral'; quasis: TemplateElement[]; expressions: Expression[]; } -interface ThrowStatement extends NodeBase { +export interface ThisExpression extends NodeBase { + type: 'ThisExpression'; +} + +export interface ThrowStatement extends NodeBase { type: 'ThrowStatement'; argument: Statement | null; } -interface TryStatement extends NodeBase { +export interface TryStatement extends NodeBase { type: 'TryStatement'; block: BlockStatement; handler: CatchClause | null; finalizer: BlockStatement; } -interface TSAbstractClassProperty extends ClassPropertyBase { +export interface TSAbstractClassProperty extends ClassPropertyBase { type: 'TSAbstractClassProperty'; } -interface TSAbstractMethodDefinition extends MethodDefinitionBase { +export interface TSAbstractKeyword extends NodeBase { + type: 'TSAbstractKeyword'; +} + +export interface TSAbstractMethodDefinition extends MethodDefinitionBase { type: 'TSAbstractMethodDefinition'; } -interface TSClassImplements extends TSHeritageBase { +export interface TSAnyKeyword extends NodeBase { + type: 'TSAnyKeyword'; +} + +export interface TSArrayType extends NodeBase { + type: 'TSTSArrayType'; + elementType: TypeNode; +} + +export interface TSAsExpression extends NodeBase { + type: 'TSAsExpression'; + expression: Expression; + typeAnnotation: TypeNode; +} + +export interface TSAsyncKeyword extends NodeBase { + type: 'TSAsyncKeyword'; +} + +export interface TSBigIntKeyword extends NodeBase { + type: 'TSBigIntKeyword'; +} + +export interface TSBooleanKeyword extends NodeBase { + type: 'TSBooleanKeyword'; +} + +export interface TSCallSignatureDeclaration extends FunctionSignatureBase { + type: 'TSCallSignatureDeclaration'; +} + +export interface TSClassImplements extends TSHeritageBase { type: 'TSClassImplements'; } -interface TSDeclareFunction extends NodeBase { +export interface TSConditionalType extends NodeBase { + type: 'TSConditionalType'; + checkType: TypeNode; + extendsType: TypeNode; + trueType: TypeNode; + falseType: TypeNode; +} + +export interface TSConstKeyword extends NodeBase { + type: 'TSConstKeyword'; +} + +export interface TSConstructorType extends FunctionSignatureBase { + type: 'TSConstructorType'; +} + +export interface TSConstructSignatureDeclaration extends FunctionSignatureBase { + type: 'TSConstructSignatureDeclaration'; +} + +export interface TSDeclareFunction extends NodeBase { type: 'TSDeclareFunction'; id: Identifier | null; generator: boolean; - expression: false; + expression: boolean; async: boolean; params: Parameter; body: BlockStatement | null | undefined; returnType?: TSTypeAnnotation; - declare: true; + declare: boolean; typeParameters?: TSTypeParameterDeclaration; } -interface TSExportAssignment extends NodeBase { +export interface TSDeclareKeyword extends NodeBase { + type: 'TSDeclareKeyword'; +} + +export interface TSDefaultKeyword extends NodeBase { + type: 'TSDefaultKeyword'; +} + +export interface TSEnumDeclaration extends NodeBase { + type: 'TSEnumDeclaration'; + id: Identifier; + members: TSEnumMember[]; + const?: boolean; + declare?: boolean; + modifiers?: Modifier[]; + decorators?: Decorator[]; +} + +export interface TSEnumMember extends NodeBase { + type: 'TSEnumMember'; + id: PropertyName; + initializer?: Expression; +} + +export interface TSExportAssignment extends NodeBase { type: 'TSExportAssignment'; expression: Expression; } -interface TSInterfaceHeritage extends TSHeritageBase { +export interface TSExportKeyword extends NodeBase { + type: 'TSExportKeyword'; +} + +export interface TSExternalModuleReference extends NodeBase { + type: 'TSExternalModuleReference'; + expression: Expression; +} + +export interface TSFunctionType extends FunctionSignatureBase { + type: 'TSFunctionType'; +} + +export interface TSImportEqualsDeclaration extends NodeBase { + type: 'TSImportEqualsDeclaration'; + id: Identifier; + moduleReference: EntityName | TSExternalModuleReference; + isExport: boolean; +} + +export interface TSImportType extends NodeBase { + type: 'TSImportType'; + isTypeOf: boolean; + parameter: TypeNode; + qualifier: EntityName | null; + typeParameters: TSTypeParameterInstantiation | null; +} + +export interface TSIndexedAccessType extends NodeBase { + type: 'TSIndexedAccessType'; + objectType: TypeNode; + indexType: TypeNode; +} + +export interface TSIndexSignature extends NodeBase { + type: 'TSIndexSignature'; + parameters: Parameter; + typeAnnotation?: TSTypeAnnotation; + readonly?: boolean; + accessibility?: Accessibility; + export?: boolean; + static?: boolean; +} + +export interface TSInferType extends NodeBase { + type: 'TSInferType'; + typeParameter: TSTypeParameterDeclaration; +} + +export interface TSInterfaceDeclaration extends NodeBase { + type: 'TSInterfaceDeclaration'; + body: TSInterfaceBody; + id: Identifier; + typeParameters?: TSTypeParameterDeclaration; + extends?: ExpressionWithTypeArguments[]; + implements?: ExpressionWithTypeArguments[]; + decorators?: Decorator[]; + abstract?: boolean; + declare?: boolean; +} + +export interface TSInterfaceBody extends NodeBase { + type: 'TSInterfaceBody'; + body: TypeElement[]; +} + +export interface TSInterfaceHeritage extends TSHeritageBase { type: 'TSInterfaceHeritage'; } -interface TSModuleBlock extends NodeBase { +export interface TSIntersectionType extends NodeBase { + type: 'TSIntersectionType'; + types: TypeNode[]; +} + +export interface TSLiteralType extends NodeBase { + type: 'TSLiteralType'; + literal: LiteralExpression | UnaryExpression | UpdateExpression; +} + +export interface TSMappedType extends NodeBase { + type: 'TSMappedType'; + typeParameter: TSTypeParameterDeclaration; + readonly?: boolean | '-' | '+'; + optional?: boolean | '-' | '+'; + typeAnnotation?: TypeNode; +} + +export interface TSMethodSignature extends NodeBase { + type: 'TSMethodSignature'; + computed: boolean; + key: PropertyName; + params: Parameter[]; + optional?: boolean; + returnType?: TypeNode; + readonly?: boolean; + typeParameters?: TSTypeParameterDeclaration; + accessibility?: Accessibility; + export?: boolean; + static?: boolean; +} + +export interface TSModuleBlock extends NodeBase { type: 'TSModuleBlock'; body: Statement[]; } -interface TSNullKeyword extends NodeBase { +export interface TSModuleDeclaration extends NodeBase { + type: 'TSModuleDeclaration'; + id: Identifier | Literal; + body?: TSModuleBlock | Identifier; + global?: boolean; +} + +export interface TSNamespaceExportDeclaration extends NodeBase { + type: 'TSNamespaceExportDeclaration'; + id: Identifier; +} + +export interface TSNeverKeyword extends NodeBase { + type: 'TSNeverKeyword'; +} + +export interface TSNonNullExpression extends NodeBase { + type: 'TSNonNullExpression'; + expression: Expression; +} + +export interface TSNullKeyword extends NodeBase { type: 'TSNullKeyword'; } -interface TSParameterProperty extends NodeBase { +export interface TSNumberKeyword extends NodeBase { + type: 'TSNumberKeyword'; +} + +export interface TSObjectKeyword extends NodeBase { + type: 'TSObjectKeyword'; +} + +export interface TSOptionalType extends NodeBase { + type: 'TSOptionalType'; + typeAnnotation: TypeNode; +} + +export interface TSParameterProperty extends NodeBase { type: 'TSParameterProperty'; accessibility: Accessibility | undefined; readonly: boolean | undefined; @@ -602,52 +943,188 @@ interface TSParameterProperty extends NodeBase { parameter: AssignmentPattern | BindingName | RestElement; } -interface TSTypeOperator extends NodeBase { +export interface TSParenthesizedType extends NodeBase { + type: 'TSParenthesizedType'; + typeAnnotation: TypeNode; +} + +export interface TSPropertySignature extends NodeBase { + type: 'TSPropertySignature'; + optional: boolean | undefined; + computed: boolean; + key: PropertyName; + typeAnnotation: TSTypeAnnotation | undefined; + initializer: Expression | undefined; + readonly: boolean | undefined; + static: boolean | undefined; + export: boolean | undefined; + accessability?: Accessibility; +} + +export interface TSPublicKeyword extends NodeBase { + type: 'TSPublicKeyword'; +} + +export interface TSPrivateKeyword extends NodeBase { + type: 'TSPrivateKeyword'; +} + +export interface TSProtectedKeyword extends NodeBase { + type: 'TSProtectedKeyword'; +} + +export interface TSQualifiedName extends NodeBase { + type: 'TSQualifiedName'; + left: EntityName; + right: Identifier; +} + +export interface TSReadonlyKeyword extends NodeBase { + type: 'TSReadonlyKeyword'; +} + +export interface TSRestType extends NodeBase { + type: 'TSRestType'; + typeAnnotation: TypeNode; +} + +export interface TSStaticKeyword extends NodeBase { + type: 'TSStaticKeyword'; +} + +export interface TSStringKeyword extends NodeBase { + type: 'TSStringKeyword'; +} + +export interface TSSymbolKeyword extends NodeBase { + type: 'TSSymbolKeyword'; +} + +export interface TSThisType extends NodeBase { + type: 'TSThisType'; +} + +export interface TSTupleType extends NodeBase { + type: 'TSTupleType'; + elementTypes: TypeNode[]; +} + +export interface TSTypeAliasDeclaration extends NodeBase { + type: 'TSTypeAliasDeclaration'; + id: Identifier; + typeAnnotation: TypeNode; + declare?: boolean; + typeParameters?: TSTypeParameterDeclaration; +} + +export interface TSTypeAnnotation extends NodeBase { + type: 'TSTypeAnnotation'; + typeAnnotation: TypeNode; +} + +export interface TSTypeAssertion extends NodeBase { + type: 'TSTypeAssertion'; + typeAnnotation: TypeNode; + expression: UnaryExpression; +} + +export interface TSTypeLiteral extends NodeBase { + type: 'TSTypeLiteral'; + members: TypeElement; +} + +export interface TSTypeOperator extends NodeBase { type: 'TSTypeOperator'; operator: 'keyof' | 'unique'; typeAnnotation?: TSTypeAnnotation; } -interface TSTypeParameterDeclaration extends NodeBase { +export interface TSTypeParameter extends NodeBase { + type: 'TSTypeParameter'; + name: Identifier; + constraint: TypeNode | undefined; + default: TypeNode | undefined; +} + +export interface TSTypeParameterDeclaration extends NodeBase { type: 'TSTypeParameterDeclaration'; params: TSTypeParameter[]; } -interface UpdateExpression extends UnaryExpressionBase { +export interface TSTypeParameterInstantiation extends NodeBase { + type: 'TSTypeParameterInstantiation'; + params: TypeNode[]; +} + +export interface TSTypePredicate extends NodeBase { + type: 'TSTypePredicate'; + parameterName: Identifier | TSThisType; + typeAnnotation: TypeNode; +} + +export interface TSTypeQuery extends NodeBase { + type: 'TSTypeQuery'; + exprName: EntityName; +} + +export interface TSTypeReference extends NodeBase { + type: 'TSTypeReference'; + typeName: EntityName; + typeParameters: TSTypeParameterInstantiation; +} + +export interface TSUndefinedKeyword extends NodeBase { + type: 'TSUndefinedKeyword'; +} + +export interface TSUnionType extends NodeBase { + type: 'TSUnionType'; + types: TypeNode[]; +} + +export interface TSUnknownKeyword extends NodeBase { + type: 'TSUnknownKeyword'; +} + +export interface TSVoidKeyword extends NodeBase { + type: 'TSVoidKeyword'; +} + +export interface UpdateExpression extends UnaryExpressionBase { type: 'UpdateExpression'; } -interface UnaryExpression extends UnaryExpressionBase { +export interface UnaryExpression extends UnaryExpressionBase { type: 'UnaryExpression'; } -interface VariableDeclaration extends NodeBase { +export interface VariableDeclaration extends NodeBase { type: 'VariableDeclaration'; declarations: VariableDeclarator[]; kind: 'let' | 'const' | 'var'; declare?: boolean; } -interface VariableDeclarator extends NodeBase { +export interface VariableDeclarator extends NodeBase { type: 'VariableDeclarator'; id: BindingName; init: Expression | null; definite?: boolean; } -interface WhileStatement extends NodeBase { +export interface WhileStatement extends NodeBase { type: 'WhileStatement'; test: Expression; body: Statement; } -interface WithStatement extends NodeBase { +export interface WithStatement extends NodeBase { type: 'WithStatement'; object: Expression; body: Statement; } -interface YieldExpression extends NodeBase { +export interface YieldExpression extends NodeBase { type: 'YieldExpression'; delegate: boolean; argument?: Expression; From 26e7275d2a6a2eb8bd5aa05e0ef15835173e4ab2 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Wed, 30 Jan 2019 11:49:49 -0800 Subject: [PATCH 15/92] Filled out unions --- packages/typescript-estree/src/typedefs.ts | 97 ++++++++++++++++++---- 1 file changed, 80 insertions(+), 17 deletions(-) diff --git a/packages/typescript-estree/src/typedefs.ts b/packages/typescript-estree/src/typedefs.ts index 77ec380030f8..1d2ed60c0e33 100644 --- a/packages/typescript-estree/src/typedefs.ts +++ b/packages/typescript-estree/src/typedefs.ts @@ -37,14 +37,10 @@ interface NodeBase { // source?: string | null; } -//////////////// NOTE - got to line 1838 //////////////////// - -// ensure you sort the union members alphabetically... -export type Node = null; // TODO - ////////// // Reusable Unions // These are based off of types used in the Typescript AST definitions +// **Ensure you sort the union members alphabetically** ////////// type Accessibility = 'public' | 'protected' | 'private'; @@ -57,14 +53,50 @@ type ClassElement = | TSAbstractClassProperty | TSAbstractMethodDefinition | TSIndexSignature; +type DeclarationStatement = + | ClassDeclaration + | ClassExpression + | ExportAllDeclaration + | ExportNamedDeclaration + | FunctionDeclaration + | TSDeclareFunction + | TSImportEqualsDeclaration + | TSInterfaceDeclaration + | TSModuleDeclaration + | TSNamespaceExportDeclaration + | TSTypeAliasDeclaration + | TSEnumDeclaration; type EntityName = Identifier | TSQualifiedName; -type Expression = null; // TODO - get lists from ts source and convert to estree nodes +type Expression = + | ArrowFunctionExpression + | AssignmentExpression + | BinaryExpression + | ConditionalExpression + | JSXClosingElement + | JSXClosingFragment + | JSXExpressionContainer + | JSXOpeningElement + | JSXOpeningFragment + | JSXSpreadChild + | LogicalExpression + | RestElement + | SequenceExpression + | SpreadElement + | TSAsExpression + | TSUnaryExpression + | YieldExpression; type ExpressionWithTypeArguments = TSClassImplements | TSInterfaceHeritage; type ForInitialiser = Expression | VariableDeclaration; type ImportClause = | ImportDefaultSpecifier | ImportNamespaceSpecifier | ImportSpecifier; +type IterationStatement = + | DoWhileStatement + | ForInStatement + | ForOfStatement + | ForStatement + | WhileStatement; type JSXChild = JSXElement | JSXExpression | JSXFragment | JSXText; type JSXExpression = | JSXEmptyExpression @@ -72,23 +104,15 @@ type JSXExpression = | JSXExpressionContainer; type JSXTagNameExpression = Identifier | MemberExpression | ThisExpression; type LeftHandSideExpression = - | ArrayExpression - | ArrayPattern | CallExpression | ClassExpression | ClassDeclaration - | Expression | FunctionExpression - | Import | LiteralExpression | MemberExpression - | ObjectExpression - | ObjectPattern - | Super + | PrimaryExpression | TaggedTemplateExpression - | ThisExpression - | TSNonNullExpression - | TSNullKeyword; + | TSNonNullExpression; type LiteralExpression = BigIntLiteral | Literal | TemplateLiteral; type Modifier = | TSAbstractKeyword @@ -109,8 +133,45 @@ type ObjectLiteralElementLike = | SpreadElement | TSAbstractMethodDefinition; type Parameter = AssignmentPattern | RestElement | TSParameterProperty; +type PrimaryExpression = + | ArrayExpression + | ArrayPattern + | ClassExpression + | FunctionExpression + | Identifier + | Import + | JSXElement + | JSXFragment + | JSXOpeningElement + | Literal + | LiteralExpression + | MetaProperty + | ObjectExpression + | ObjectPattern + | Super + | TemplateLiteral + | ThisExpression + | TSNullKeyword; type PropertyName = Identifier | Literal; -type Statement = null; // TODO - get lists from ts source and convert to estree nodes +type Statement = + | BlockStatement + | BreakStatement + | ContinueStatement + | DebuggerStatement + | DeclarationStatement + | EmptyStatement + | ExpressionStatement + | IfStatement + | IterationStatement + | ImportDeclaration + | LabeledStatement + | TSModuleBlock + | ReturnStatement + | SwitchStatement + | ThrowStatement + | TryStatement + | VariableDeclaration + | WithStatement; type TypeElement = | TSCallSignatureDeclaration | TSConstructSignatureDeclaration @@ -163,6 +224,7 @@ type TSUnaryExpression = /////////////// // Base, common types +// **Ensure you sort the interfaces alphabetically** /////////////// interface BinaryExpressionBase extends NodeBase { @@ -246,6 +308,7 @@ interface UnaryExpressionBase extends NodeBase { /////////////// // Typescript ESTree Nodes +// **Ensure you sort the interfaces alphabetically** /////////////// export interface ArrayExpression extends NodeBase { From 1df60849e6909e523c7e5057074f284a567a1966 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Wed, 30 Jan 2019 11:50:54 -0800 Subject: [PATCH 16/92] removed types auto generated by armano --- .../typescript-estree/src/es-tree-nodes.ts | 1224 ----------------- 1 file changed, 1224 deletions(-) delete mode 100644 packages/typescript-estree/src/es-tree-nodes.ts diff --git a/packages/typescript-estree/src/es-tree-nodes.ts b/packages/typescript-estree/src/es-tree-nodes.ts deleted file mode 100644 index c0f68cb45d82..000000000000 --- a/packages/typescript-estree/src/es-tree-nodes.ts +++ /dev/null @@ -1,1224 +0,0 @@ -/** - * @fileoverview Definition of AST structure. - * @author Armano - */ -/* eslint-disable @typescript-eslint/array-type */ - -export interface Position { - line: number; - column: number; -} - -interface SourceLocation { - source?: string | null; - start: Position; - end: Position; -} - -export interface BaseNode { - type: string; - loc?: SourceLocation | null; - range?: [number, number]; -} - -export interface Comment extends BaseNode { - type: 'Line' | 'Block'; - value: string; -} - -export interface ArrayExpression extends BaseNode { - type: 'ArrayExpression'; - elements: Array; -} - -export interface ArrayPattern extends BaseNode { - type: 'ArrayPattern'; - optional?: boolean; - typeAnnotation?: TSTypeAnnotation; - elements: Array< - | ArrayPattern - | AssignmentPattern - | Identifier - | MemberExpression - | ObjectPattern - | RestElement - | null - >; -} - -export interface ArrowFunctionExpression extends BaseNode { - type: 'ArrowFunctionExpression'; - generator: boolean; - expression: boolean; - async: boolean; - typeParameters?: TSTypeParameterDeclaration; - returnType?: TSTypeAnnotation; - params: Array< - | ArrayPattern - | AssignmentPattern - | Identifier - | ObjectPattern - | RestElement - | TSParameterProperty - >; - id: null; - body: BlockStatement | Expressions | Identifier | JSXElement | Literals; -} - -export interface AssignmentExpression extends BaseNode { - type: 'AssignmentExpression'; - operator: - | '%=' - | '&=' - | '**=' - | '*=' - | '+=' - | '-=' - | '/=' - | '<<=' - | '=' - | '>>=' - | '>>>=' - | '^=' - | '|='; - right: Expressions | Identifier | JSXElement | Literals; - left: ArrayPattern | Expressions | Identifier | Literal | ObjectPattern; -} - -export interface AssignmentPattern extends BaseNode { - type: 'AssignmentPattern'; - right: Expressions | Identifier | Literals; - left: ArrayPattern | Identifier | ObjectPattern; -} - -export interface AwaitExpression extends BaseNode { - type: 'AwaitExpression'; - argument: Expressions | Identifier | Literal; -} - -export interface BigIntLiteral extends BaseNode { - type: 'BigIntLiteral'; - value: string; - raw: string; -} - -export interface BinaryExpression extends BaseNode { - type: 'BinaryExpression'; - operator: - | '!=' - | '!==' - | '%' - | '&' - | '*' - | '**' - | '+' - | '-' - | '/' - | '<' - | '<<' - | '<=' - | '==' - | '===' - | '>' - | '>=' - | '>>' - | '>>>' - | '^' - | 'in' - | 'instanceof' - | '|'; - right: Expressions | Identifier | Literals; - left: Expressions | Identifier | Literals; -} - -export interface BlockStatement extends BaseNode { - type: 'BlockStatement'; - body: Array; -} - -export interface BreakStatement extends BaseNode { - type: 'BreakStatement'; - label: null | Identifier; -} - -export interface CallExpression extends BaseNode { - type: 'CallExpression'; - typeParameters?: TSTypeParameterInstantiation; - callee: Expressions | Identifier | Import | Literals | Super; - arguments: Array; -} - -export interface CatchClause extends BaseNode { - type: 'CatchClause'; - param: null | ArrayPattern | Identifier | ObjectPattern; - body: BlockStatement; -} - -export interface ClassBody extends BaseNode { - type: 'ClassBody'; - body: Array< - | ClassProperty - | MethodDefinition - | TSAbstractClassProperty - | TSAbstractMethodDefinition - | TSIndexSignature - >; -} - -export interface ClassDeclaration extends BaseNode { - type: 'ClassDeclaration'; - declare?: boolean; - abstract?: boolean; - typeParameters?: TSTypeParameterDeclaration; - superTypeParameters?: TSTypeParameterInstantiation; - superClass: null | Expressions | Identifier | Literal; - implements?: Array; - id: null | Identifier; - decorators?: Array; - body: ClassBody; -} - -export interface ClassExpression extends BaseNode { - type: 'ClassExpression'; - typeParameters?: TSTypeParameterDeclaration; - superTypeParameters?: TSTypeParameterInstantiation; - superClass: null | Expressions | Identifier; - implements?: Array; - id: null | Identifier; - body: ClassBody; -} - -export interface ClassProperty extends BaseNode { - type: 'ClassProperty'; - static: boolean; - readonly?: boolean; - optional?: boolean; - definite?: boolean; - computed: boolean; - accessibility?: 'private' | 'protected' | 'public'; - value: null | Expressions | Identifier | Literal; - typeAnnotation?: TSTypeAnnotation; - key: Expressions | Identifier | Literals; - decorators?: Array; -} - -export interface ConditionalExpression extends BaseNode { - type: 'ConditionalExpression'; - test: Expressions | Identifier | Literals; - consequent: Expressions | Identifier | JSXElement | Literals; - alternate: Expressions | Identifier | JSXElement | Literals; -} - -export interface ContinueStatement extends BaseNode { - type: 'ContinueStatement'; - label: null | Identifier; -} - -export interface DebuggerStatement extends BaseNode { - type: 'DebuggerStatement'; -} - -export interface Decorator extends BaseNode { - type: 'Decorator'; - expression: Expressions | Identifier; -} - -export interface DoWhileStatement extends BaseNode { - type: 'DoWhileStatement'; - test: Expressions | Identifier | Literal; - body: BlockStatement | VariableDeclaration; -} - -export interface EmptyStatement extends BaseNode { - type: 'EmptyStatement'; -} - -export interface ExportAllDeclaration extends BaseNode { - type: 'ExportAllDeclaration'; - source: Identifier | Literal; -} - -export interface ExportDefaultDeclaration extends BaseNode { - type: 'ExportDefaultDeclaration'; - declaration: Declarations | Expressions | Identifier | JSXElement | Literal; -} - -export interface ExportNamedDeclaration extends BaseNode { - type: 'ExportNamedDeclaration'; - specifiers: Array; - source: null | Literal; - declaration: null | Declarations; -} - -export interface ExportSpecifier extends BaseNode { - type: 'ExportSpecifier'; - local: Identifier; - exported: Identifier; -} - -export interface ExpressionStatement extends BaseNode { - type: 'ExpressionStatement'; - directive?: string; - expression: Expressions | Identifier | JSXElement | JSXFragment | Literals; -} - -export interface ForInStatement extends BaseNode { - type: 'ForInStatement'; - right: Expressions | Identifier | Literal; - left: - | AssignmentPattern - | Expressions - | Identifier - | ObjectPattern - | VariableDeclaration; - body: Statements | VariableDeclaration; -} - -export interface ForOfStatement extends BaseNode { - type: 'ForOfStatement'; - await: boolean; - right: Expressions | Identifier | Literal; - left: - | ArrayPattern - | Expressions - | Identifier - | ObjectPattern - | VariableDeclaration; - body: Statements; -} - -export interface ForStatement extends BaseNode { - type: 'ForStatement'; - update: null | Expressions | Identifier; - test: null | Expressions | Identifier | Literal; - init: null | Expressions | Identifier | VariableDeclaration; - body: Statements | VariableDeclaration; -} - -export interface FunctionDeclaration extends BaseNode { - type: 'FunctionDeclaration'; - generator: boolean; - expression: boolean; - async: boolean; - typeParameters?: TSTypeParameterDeclaration; - returnType?: TSTypeAnnotation; - params: Array< - | ArrayPattern - | AssignmentPattern - | Identifier - | ObjectPattern - | RestElement - | TSParameterProperty - >; - id: null | Identifier; - body: BlockStatement; -} - -export interface FunctionExpression extends BaseNode { - type: 'FunctionExpression'; - generator: boolean; - expression: boolean; - async: boolean; - typeParameters?: TSTypeParameterDeclaration; - returnType?: TSTypeAnnotation; - params: Array< - | ArrayPattern - | AssignmentPattern - | Identifier - | ObjectPattern - | RestElement - | TSParameterProperty - >; - id: null | Identifier; - body: null | BlockStatement; -} - -export interface Identifier extends BaseNode { - type: 'Identifier'; - optional?: boolean; - name: string; - typeAnnotation?: TSTypeAnnotation; - decorators?: Array; -} - -export interface IfStatement extends BaseNode { - type: 'IfStatement'; - test: Expressions | Identifier | Literal; - consequent: Statements | VariableDeclaration; - alternate: null | Statements | VariableDeclaration; -} - -export interface Import extends BaseNode { - type: 'Import'; -} - -export interface ImportDeclaration extends BaseNode { - type: 'ImportDeclaration'; - specifiers: Array< - ImportDefaultSpecifier | ImportNamespaceSpecifier | ImportSpecifier - >; - source: Literal; -} - -export interface ImportDefaultSpecifier extends BaseNode { - type: 'ImportDefaultSpecifier'; - local: Identifier; -} - -export interface ImportNamespaceSpecifier extends BaseNode { - type: 'ImportNamespaceSpecifier'; - local: Identifier; -} - -export interface ImportSpecifier extends BaseNode { - type: 'ImportSpecifier'; - local: Identifier; - imported: Identifier; -} - -export interface JSXAttribute extends BaseNode { - type: 'JSXAttribute'; - value: null | JSXExpressionContainer | Literal; - name: JSXIdentifier; -} - -export interface JSXClosingElement extends BaseNode { - type: 'JSXClosingElement'; - name: JSXIdentifier | JSXMemberExpression; -} - -export interface JSXClosingFragment extends BaseNode { - type: 'JSXClosingFragment'; -} - -export interface JSXElement extends BaseNode { - type: 'JSXElement'; - openingElement: JSXOpeningElement; - closingElement: null | JSXClosingElement; - children: Array< - JSXElement | JSXExpressionContainer | JSXFragment | JSXSpreadChild | JSXText - >; -} - -export interface JSXEmptyExpression extends BaseNode { - type: 'JSXEmptyExpression'; -} - -export interface JSXExpressionContainer extends BaseNode { - type: 'JSXExpressionContainer'; - expression: - | Expressions - | Identifier - | JSXElement - | JSXEmptyExpression - | Literal; -} - -export interface JSXFragment extends BaseNode { - type: 'JSXFragment'; - openingFragment: JSXOpeningFragment; - closingFragment: JSXClosingFragment; - children: Array; -} - -export interface JSXIdentifier extends BaseNode { - type: 'JSXIdentifier'; - name: string; -} - -export interface JSXMemberExpression extends BaseNode { - type: 'JSXMemberExpression'; - property: JSXIdentifier; - object: JSXIdentifier | JSXMemberExpression | MemberExpression; -} - -export interface JSXOpeningElement extends BaseNode { - type: 'JSXOpeningElement'; - selfClosing: boolean; - typeParameters?: TSTypeParameterInstantiation; - name: JSXIdentifier | JSXMemberExpression; - attributes: Array; -} - -export interface JSXOpeningFragment extends BaseNode { - type: 'JSXOpeningFragment'; -} - -export interface JSXSpreadAttribute extends BaseNode { - type: 'JSXSpreadAttribute'; - argument: Expressions | Identifier; -} - -export interface JSXSpreadChild extends BaseNode { - type: 'JSXSpreadChild'; - expression: Expressions | JSXElement; -} - -export interface JSXText extends BaseNode { - type: 'JSXText'; - value: string; - raw: string; -} - -export interface LabeledStatement extends BaseNode { - type: 'LabeledStatement'; - label: Identifier; - body: Statements | VariableDeclaration; -} - -export interface Literal extends BaseNode { - type: 'Literal'; - value: boolean | null | number | string; - raw: string; - regex?: { - pattern: string; - flags: string; - }; -} - -export interface LogicalExpression extends BaseNode { - type: 'LogicalExpression'; - operator: '&&' | '||'; - right: Expressions | Identifier | Literal; - left: Expressions | Identifier | Literal; -} - -export interface MemberExpression extends BaseNode { - type: 'MemberExpression'; - computed: boolean; - property: Expressions | Identifier | Literals; - object: Expressions | Identifier | Literals | Super; -} - -export interface MetaProperty extends BaseNode { - type: 'MetaProperty'; - property: Identifier; - meta: Identifier; -} - -export interface MethodDefinition extends BaseNode { - type: 'MethodDefinition'; - static: boolean; - kind: 'constructor' | 'get' | 'method' | 'set'; - computed: boolean; - accessibility?: 'private' | 'protected' | 'public'; - value: FunctionExpression; - key: Expressions | Identifier | Literals; - decorators?: Array; -} - -export interface NewExpression extends BaseNode { - type: 'NewExpression'; - typeParameters?: TSTypeParameterInstantiation; - callee: Expressions | Identifier | Super | TemplateLiteral; - arguments: Array; -} - -export interface ObjectExpression extends BaseNode { - type: 'ObjectExpression'; - properties: Array; -} - -export interface ObjectPattern extends BaseNode { - type: 'ObjectPattern'; - optional?: boolean; - typeAnnotation?: TSTypeAnnotation; - properties: Array; -} - -export interface Program extends BaseNode { - type: 'Program'; - sourceType: 'module' | 'script'; - body: Array; -} - -export interface Property extends BaseNode { - type: 'Property'; - shorthand: boolean; - method: boolean; - kind: 'get' | 'init' | 'set'; - computed: boolean; - value: - | ArrayPattern - | AssignmentPattern - | Expressions - | Identifier - | Literals - | ObjectPattern; - typeParameters?: TSTypeParameterDeclaration; - key: Expressions | Identifier | Literals; -} - -export interface RestElement extends BaseNode { - type: 'RestElement'; - optional?: boolean; - typeAnnotation?: TSTypeAnnotation; - decorators?: Array; - argument: ArrayPattern | AssignmentPattern | Identifier | ObjectPattern; -} - -export interface ReturnStatement extends BaseNode { - type: 'ReturnStatement'; - argument: - | null - | Expressions - | Identifier - | JSXElement - | JSXFragment - | Literals; -} - -export interface SequenceExpression extends BaseNode { - type: 'SequenceExpression'; - expressions: Array; -} - -export interface SpreadElement extends BaseNode { - type: 'SpreadElement'; - argument: Expressions | Identifier; -} - -export interface Super extends BaseNode { - type: 'Super'; -} - -export interface SwitchCase extends BaseNode { - type: 'SwitchCase'; - test: null | Expressions | Identifier | Literals; - consequent: Array; -} - -export interface SwitchStatement extends BaseNode { - type: 'SwitchStatement'; - discriminant: Expressions | Identifier | Literals; - cases: Array; -} - -export interface TaggedTemplateExpression extends BaseNode { - type: 'TaggedTemplateExpression'; - typeParameters?: TSTypeParameterInstantiation; - tag: Identifier | MemberExpression | TemplateLiteral; - quasi: TemplateLiteral; -} - -export interface TemplateElement extends BaseNode { - type: 'TemplateElement'; - tail: boolean; - value: { - raw: string; - cooked: string; - }; -} - -export interface TemplateLiteral extends BaseNode { - type: 'TemplateLiteral'; - quasis: Array; - expressions: Array; -} - -export interface ThisExpression extends BaseNode { - type: 'ThisExpression'; -} - -export interface ThrowStatement extends BaseNode { - type: 'ThrowStatement'; - argument: null | Expressions | Identifier | Literal; -} - -export interface TryStatement extends BaseNode { - type: 'TryStatement'; - handler: null | CatchClause; - finalizer: null | BlockStatement; - block: BlockStatement; -} - -export interface UnaryExpression extends BaseNode { - type: 'UnaryExpression'; - prefix: boolean; - operator: '!' | '+' | '-' | 'delete' | 'typeof' | 'void' | '~'; - argument: Expressions | Identifier | Literals; -} - -export interface UpdateExpression extends BaseNode { - type: 'UpdateExpression'; - prefix: boolean; - operator: '++' | '--'; - argument: Expressions | Identifier | Literal; -} - -export interface VariableDeclaration extends BaseNode { - type: 'VariableDeclaration'; - kind: 'const' | 'let' | 'var'; - declare?: boolean; - declarations: Array; -} - -export interface VariableDeclarator extends BaseNode { - type: 'VariableDeclarator'; - definite?: boolean; - init: null | Expressions | Identifier | JSXElement | Literals; - id: ArrayPattern | Identifier | ObjectPattern; -} - -export interface WhileStatement extends BaseNode { - type: 'WhileStatement'; - test: Expressions | Identifier | Literals; - body: Statements | VariableDeclaration; -} - -export interface WithStatement extends BaseNode { - type: 'WithStatement'; - object: Expressions | Identifier | Literal; - body: Statements | VariableDeclaration; -} - -export interface YieldExpression extends BaseNode { - type: 'YieldExpression'; - delegate: boolean; - argument: null | Expressions | Identifier | Literals; -} - -export interface TSAbstractClassProperty extends BaseNode { - type: 'TSAbstractClassProperty'; - static: boolean; - readonly?: boolean; - optional?: boolean; - definite: boolean; - computed: boolean; - accessibility?: 'private' | 'protected' | 'public'; - value: null; - typeAnnotation?: TSTypeAnnotation; - key: Identifier; -} - -export interface TSAbstractMethodDefinition extends BaseNode { - type: 'TSAbstractMethodDefinition'; - static: boolean; - kind: 'constructor' | 'get' | 'method' | 'set'; - computed: boolean; - accessibility?: 'private' | 'protected' | 'public'; - value: FunctionExpression; - key: Identifier; -} - -export interface TSArrayType extends BaseNode { - type: 'TSArrayType'; - elementType: TSTypeKeywords | TSTypeOperators; -} - -export interface TSAsExpression extends BaseNode { - type: 'TSAsExpression'; - typeAnnotation: TSLiteralType | TSTypeKeywords | TSTypeOperators; - expression: Expressions | Identifier | JSXElement | Literals; -} - -export interface TSCallSignatureDeclaration extends BaseNode { - type: 'TSCallSignatureDeclaration'; - typeParameters?: TSTypeParameterDeclaration; - returnType?: TSTypeAnnotation; - params: Array; -} - -export interface TSClassImplements extends BaseNode { - type: 'TSClassImplements'; - typeParameters?: TSTypeParameterInstantiation; - expression: Identifier | MemberExpression; -} - -export interface TSConditionalType extends BaseNode { - type: 'TSConditionalType'; - trueType: TSLiteralType | TSTypeKeywords | TSTypeOperators; - falseType: TSLiteralType | TSTypeKeywords | TSTypeOperators; - extendsType: TSLiteralType | TSTypeKeywords | TSTypeOperators; - checkType: TSTypeKeywords | TSTypeOperators; -} - -export interface TSConstructSignatureDeclaration extends BaseNode { - type: 'TSConstructSignatureDeclaration'; - typeParameters?: TSTypeParameterDeclaration; - returnType?: TSTypeAnnotation; - params: Array; -} - -export interface TSConstructorType extends BaseNode { - type: 'TSConstructorType'; - typeParameters?: TSTypeParameterDeclaration; - returnType: TSTypeAnnotation; - params: Array; -} - -export interface TSDeclareFunction extends BaseNode { - type: 'TSDeclareFunction'; - generator: boolean; - expression: boolean; - declare?: boolean; - async: boolean; - typeParameters?: TSTypeParameterDeclaration; - returnType?: TSTypeAnnotation; - params: Array< - ArrayPattern | AssignmentPattern | Identifier | ObjectPattern | RestElement - >; - id: Identifier; - body?: BlockStatement; -} - -export interface TSEnumDeclaration extends BaseNode { - type: 'TSEnumDeclaration'; - declare?: boolean; - const?: boolean; - modifiers?: Array< - TSAsyncKeyword | TSPrivateKeyword | TSPublicKeyword | TSStaticKeyword - >; - members: Array; - id: Identifier; - decorators?: Array; -} - -export interface TSEnumMember extends BaseNode { - type: 'TSEnumMember'; - initializer?: Expressions | Identifier | Literal; - id: Identifier | Literal; -} - -export interface TSExportAssignment extends BaseNode { - type: 'TSExportAssignment'; - expression: Expressions | Identifier | Literal; -} - -export interface TSExternalModuleReference extends BaseNode { - type: 'TSExternalModuleReference'; - expression: Identifier | Literal; -} - -export interface TSFunctionType extends BaseNode { - type: 'TSFunctionType'; - typeParameters?: TSTypeParameterDeclaration; - returnType: TSTypeAnnotation; - params: Array< - | ArrayPattern - | AssignmentPattern - | Identifier - | ObjectPattern - | RestElement - | TSParameterProperty - >; -} - -export interface TSImportEqualsDeclaration extends BaseNode { - type: 'TSImportEqualsDeclaration'; - isExport: boolean; - moduleReference: Identifier | TSExternalModuleReference | TSQualifiedName; - id: Identifier; -} - -export interface TSImportType extends BaseNode { - type: 'TSImportType'; - isTypeOf: boolean; - typeParameters: null | TSTypeParameterInstantiation; - qualifier: null | Identifier; - parameter: TSLiteralType; -} - -export interface TSIndexSignature extends BaseNode { - type: 'TSIndexSignature'; - static?: boolean; - readonly?: boolean; - export?: boolean; - accessibility?: 'private' | 'public'; - typeAnnotation?: TSTypeAnnotation; - parameters: Array< - AssignmentPattern | Identifier | RestElement | TSParameterProperty - >; -} - -export interface TSIndexedAccessType extends BaseNode { - type: 'TSIndexedAccessType'; - objectType: TSTypeOperators | TSAnyKeyword; - indexType: TSLiteralType | TSTypeOperators | TSNeverKeyword; -} - -export interface TSInferType extends BaseNode { - type: 'TSInferType'; - typeParameter: TSTypeParameter; -} - -export interface TSInterfaceBody extends BaseNode { - type: 'TSInterfaceBody'; - body: Array; -} - -export interface TSInterfaceDeclaration extends BaseNode { - type: 'TSInterfaceDeclaration'; - declare?: boolean; - abstract?: boolean; - typeParameters?: TSTypeParameterDeclaration; - implements?: Array; - id: Identifier; - extends?: Array; - decorators?: Array; - body: TSInterfaceBody; -} - -export interface TSInterfaceHeritage extends BaseNode { - type: 'TSInterfaceHeritage'; - typeParameters?: TSTypeParameterInstantiation; - expression: Expressions | Identifier; -} - -export interface TSIntersectionType extends BaseNode { - type: 'TSIntersectionType'; - types: Array; -} - -export interface TSLiteralType extends BaseNode { - type: 'TSLiteralType'; - literal: Literals | UnaryExpression; -} - -export interface TSMappedType extends BaseNode { - type: 'TSMappedType'; - readonly?: boolean; - optional?: boolean | '-'; - typeParameter: TSTypeParameter; - typeAnnotation?: TSLiteralType | TSTypeKeywords | TSTypeOperators; -} - -export interface TSMethodSignature extends BaseNode { - type: 'TSMethodSignature'; - optional?: boolean; - computed: boolean; - typeParameters?: TSTypeParameterDeclaration; - returnType?: TSTypeAnnotation; - params: Array< - ArrayPattern | AssignmentPattern | Identifier | ObjectPattern | RestElement - >; - key: Expressions | Identifier | Literal; -} - -export interface TSModuleBlock extends BaseNode { - type: 'TSModuleBlock'; - body: Array; -} - -export interface TSModuleDeclaration extends BaseNode { - type: 'TSModuleDeclaration'; - global?: boolean; - declare?: boolean; - modifiers?: Array< - | TSAsyncKeyword - | TSPrivateKeyword - | TSProtectedKeyword - | TSPublicKeyword - | TSStaticKeyword - >; - id: Identifier | Literal; - body?: TSModuleBlock | TSModuleDeclaration; -} - -export interface TSNamespaceExportDeclaration extends BaseNode { - type: 'TSNamespaceExportDeclaration'; - id: Identifier; -} - -export interface TSNonNullExpression extends BaseNode { - type: 'TSNonNullExpression'; - expression: Expressions | Identifier | Literal; -} - -export interface TSOptionalType extends BaseNode { - type: 'TSOptionalType'; - typeAnnotation: TSStringKeyword; -} - -export interface TSParameterProperty extends BaseNode { - type: 'TSParameterProperty'; - static?: boolean; - readonly?: boolean; - export?: boolean; - accessibility?: 'private' | 'protected' | 'public'; - parameter: - | ArrayPattern - | AssignmentPattern - | Identifier - | ObjectPattern - | RestElement; - decorators?: Array; -} - -export interface TSParenthesizedType extends BaseNode { - type: 'TSParenthesizedType'; - typeAnnotation: TSLiteralType | TSTypeOperators; -} - -export interface TSPropertySignature extends BaseNode { - type: 'TSPropertySignature'; - readonly?: boolean; - optional?: boolean; - computed: boolean; - accessibility?: 'private' | 'protected' | 'public'; - typeAnnotation?: TSTypeAnnotation; - key: Expressions | Identifier | Literal; - initializer?: Literal; -} - -export interface TSQualifiedName extends BaseNode { - type: 'TSQualifiedName'; - right: Identifier; - left: Identifier | TSQualifiedName; -} - -export interface TSRestType extends BaseNode { - type: 'TSRestType'; - typeAnnotation: TSTypeOperators; -} - -export interface TSThisType extends BaseNode { - type: 'TSThisType'; -} - -export interface TSTupleType extends BaseNode { - type: 'TSTupleType'; - elementTypes: Array; -} - -export interface TSTypeAliasDeclaration extends BaseNode { - type: 'TSTypeAliasDeclaration'; - declare?: boolean; - typeParameters?: TSTypeParameterDeclaration; - typeAnnotation: TSLiteralType | TSThisType | TSTypeKeywords | TSTypeOperators; - id: Identifier; -} - -export interface TSTypeAnnotation extends BaseNode { - type: 'TSTypeAnnotation'; - typeAnnotation: TSLiteralType | TSThisType | TSTypeKeywords | TSTypeOperators; -} - -export interface TSTypeAssertion extends BaseNode { - type: 'TSTypeAssertion'; - typeAnnotation: TSTypeKeywords | TSTypeOperators; - expression: Expressions | Identifier | Literals; -} - -export interface TSTypeLiteral extends BaseNode { - type: 'TSTypeLiteral'; - members: Array; -} - -export interface TSTypeOperator extends BaseNode { - type: 'TSTypeOperator'; - operator: 'keyof' | 'unique'; - typeAnnotation: TSTypeKeywords | TSTypeOperators; -} - -export interface TSTypeParameter extends BaseNode { - type: 'TSTypeParameter'; - name: Identifier; - default?: TSLiteralType | TSTypeKeywords | TSTypeOperators; - constraint?: TSLiteralType | TSThisType | TSTypeKeywords | TSTypeOperators; -} - -export interface TSTypeParameterDeclaration extends BaseNode { - type: 'TSTypeParameterDeclaration'; - params: Array; -} - -export interface TSTypeParameterInstantiation extends BaseNode { - type: 'TSTypeParameterInstantiation'; - params: Array; -} - -export interface TSTypePredicate extends BaseNode { - type: 'TSTypePredicate'; - typeAnnotation: TSTypeAnnotation; - parameterName: Identifier | TSThisType; -} - -export interface TSTypeQuery extends BaseNode { - type: 'TSTypeQuery'; - exprName: Identifier | TSQualifiedName; -} - -export interface TSTypeReference extends BaseNode { - type: 'TSTypeReference'; - typeParameters?: TSTypeParameterInstantiation; - typeName: Identifier | TSQualifiedName; -} - -export interface TSUnionType extends BaseNode { - type: 'TSUnionType'; - types: Array; -} - -export interface TSAnyKeyword extends BaseNode { - type: 'TSAnyKeyword'; -} - -export interface TSAsyncKeyword extends BaseNode { - type: 'TSAsyncKeyword'; -} - -export interface TSBigIntKeyword extends BaseNode { - type: 'TSBigIntKeyword'; -} - -export interface TSBooleanKeyword extends BaseNode { - type: 'TSBooleanKeyword'; -} - -export interface TSNeverKeyword extends BaseNode { - type: 'TSNeverKeyword'; -} - -export interface TSNullKeyword extends BaseNode { - type: 'TSNullKeyword'; -} - -export interface TSNumberKeyword extends BaseNode { - type: 'TSNumberKeyword'; -} - -export interface TSObjectKeyword extends BaseNode { - type: 'TSObjectKeyword'; -} - -export interface TSPrivateKeyword extends BaseNode { - type: 'TSPrivateKeyword'; -} - -export interface TSProtectedKeyword extends BaseNode { - type: 'TSProtectedKeyword'; -} - -export interface TSPublicKeyword extends BaseNode { - type: 'TSPublicKeyword'; -} - -export interface TSStaticKeyword extends BaseNode { - type: 'TSStaticKeyword'; -} - -export interface TSStringKeyword extends BaseNode { - type: 'TSStringKeyword'; -} - -export interface TSSymbolKeyword extends BaseNode { - type: 'TSSymbolKeyword'; -} - -export interface TSUndefinedKeyword extends BaseNode { - type: 'TSUndefinedKeyword'; -} - -export interface TSUnknownKeyword extends BaseNode { - type: 'TSUnknownKeyword'; -} - -export interface TSVoidKeyword extends BaseNode { - type: 'TSVoidKeyword'; -} - -export type Declarations = - | ClassDeclaration - | ExportAllDeclaration - | ExportDefaultDeclaration - | ExportNamedDeclaration - | FunctionDeclaration - | ImportDeclaration - | VariableDeclaration - | TSDeclareFunction - | TSEnumDeclaration - | TSExportAssignment - | TSImportEqualsDeclaration - | TSInterfaceDeclaration - | TSModuleDeclaration - | TSTypeAliasDeclaration; - -export type Statements = - | ExpressionStatement - | BlockStatement - | EmptyStatement - | DebuggerStatement - | WithStatement - | ReturnStatement - | LabeledStatement - | BreakStatement - | ContinueStatement - | IfStatement - | SwitchStatement - | ThrowStatement - | TryStatement - | WhileStatement - | DoWhileStatement - | ForStatement - | ForInStatement - | ForOfStatement; - -export type Literals = TemplateLiteral | Literal | BigIntLiteral; - -export type Expressions = - | ThisExpression - | ArrayExpression - | ObjectExpression - | FunctionExpression - | ArrowFunctionExpression - | YieldExpression - | UnaryExpression - | UpdateExpression - | BinaryExpression - | AssignmentExpression - | LogicalExpression - | MemberExpression - | ConditionalExpression - | CallExpression - | NewExpression - | SequenceExpression - | TaggedTemplateExpression - | ClassExpression - | MetaProperty - | AwaitExpression - | TSAsExpression - | TSNonNullExpression - | TSTypeAssertion; - -export type TSSignatures = - | TSCallSignatureDeclaration - | TSConstructSignatureDeclaration - | TSIndexSignature - | TSMethodSignature - | TSPropertySignature; - -export type TSTypeKeywords = - | TSAnyKeyword - | TSBigIntKeyword - | TSBooleanKeyword - | TSNeverKeyword - | TSNullKeyword - | TSNumberKeyword - | TSObjectKeyword - | TSStringKeyword - | TSSymbolKeyword - | TSUndefinedKeyword - | TSUnknownKeyword - | TSVoidKeyword; - -export type TSTypeOperators = - | TSArrayType - | TSConditionalType - | TSConstructorType - | TSFunctionType - | TSImportType - | TSIndexedAccessType - | TSInferType - | TSIntersectionType - | TSMappedType - | TSParenthesizedType - | TSTupleType - | TSTypeLiteral - | TSTypeOperator - | TSTypePredicate - | TSTypeQuery - | TSTypeReference - | TSUnionType - | TSOptionalType - | TSRestType; From 25579adf7586792b5fa08885005d5c326d859d12 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Wed, 30 Jan 2019 14:14:54 -0800 Subject: [PATCH 17/92] Fix some incorrect typings --- packages/parser/src/parser.ts | 12 +- packages/typescript-estree/src/parser.ts | 2 + packages/typescript-estree/src/typedefs.ts | 228 ++++++++++++++++++--- 3 files changed, 207 insertions(+), 35 deletions(-) diff --git a/packages/parser/src/parser.ts b/packages/parser/src/parser.ts index 2dd32b383625..51977e5d2692 100644 --- a/packages/parser/src/parser.ts +++ b/packages/parser/src/parser.ts @@ -2,21 +2,15 @@ import traverser from 'eslint/lib/util/traverser'; import { AST_NODE_TYPES, parseAndGenerateServices, - ParserOptions as ParserOptionsTsESTree + ParserOptions as ParserOptionsTsESTree, + ParserServices } from '@typescript-eslint/typescript-estree'; import { analyzeScope } from './analyze-scope'; import { ParserOptions } from './parser-options'; import { visitorKeys } from './visitor-keys'; -import { Program } from 'typescript'; const packageJSON = require('../package.json'); -interface ParserServices { - program: Program | undefined; - esTreeNodeToTSNodeMap: WeakMap | undefined; - tsNodeToESTreeNodeMap: WeakMap | undefined; -} - interface ParseForESLintResult { ast: any; services: ParserServices; @@ -95,3 +89,5 @@ export function parseForESLint( const scopeManager = analyzeScope(ast, options); return { ast, services, scopeManager, visitorKeys }; } + +export { ParserServices }; diff --git a/packages/typescript-estree/src/parser.ts b/packages/typescript-estree/src/parser.ts index 362ad3885df9..7766e728844b 100644 --- a/packages/typescript-estree/src/parser.ts +++ b/packages/typescript-estree/src/parser.ts @@ -22,6 +22,7 @@ import { ParserOptions } from './temp-types-based-on-js-source'; import { getFirstSemanticOrSyntacticError } from './semantic-errors'; +import * as TSESTree from './typedefs'; const packageJSON = require('../package.json'); @@ -383,3 +384,4 @@ export function parseAndGenerateServices( export { AST_NODE_TYPES } from './ast-node-types'; export { ParserOptions }; +export { TSESTree }; diff --git a/packages/typescript-estree/src/typedefs.ts b/packages/typescript-estree/src/typedefs.ts index 1d2ed60c0e33..62e764a0a221 100644 --- a/packages/typescript-estree/src/typedefs.ts +++ b/packages/typescript-estree/src/typedefs.ts @@ -37,23 +37,182 @@ interface NodeBase { // source?: string | null; } +export type Node = + | ArrayExpression + | ArrayPattern + | ArrowFunctionExpression + | AssignmentExpression + | AssignmentPattern + | AwaitExpression + | BigIntLiteral + | BinaryExpression + | BlockStatement + | BreakStatement + | CallExpression + | CatchClause + | ClassBody + | ClassDeclaration + | ClassExpression + | ClassProperty + | ConditionalExpression + | ContinueStatement + | DebuggerStatement + | Decorator + | DoWhileStatement + | EmptyStatement + | ExportAllDeclaration + | ExportDefaultDeclaration + | ExportNamedDeclaration + | ExportSpecifier + | ExpressionStatement + | ForInStatement + | ForOfStatement + | ForStatement + | FunctionDeclaration + | FunctionExpression + | Identifier + | IfStatement + | Import + | ImportDeclaration + | ImportDefaultSpecifier + | ImportNamespaceSpecifier + | ImportSpecifier + | JSXAttribute + | JSXClosingElement + | JSXClosingFragment + | JSXElement + | JSXEmptyExpression + | JSXExpressionContainer + | JSXFragment + | JSXIdentifier + | JSXOpeningElement + | JSXOpeningFragment + | JSXSpreadAttribute + | JSXSpreadChild + | JSXText + | LabeledStatement + | Literal + | LogicalExpression + | MemberExpression + | MetaProperty + | MethodDefinition + | NewExpression + | ObjectExpression + | ObjectPattern + | Program + | Property + | RestElement + | ReturnStatement + | SequenceExpression + | SpreadElement + | Super + | SwitchCase + | SwitchStatement + | TaggedTemplateExpression + | TemplateElement + | TemplateLiteral + | ThisExpression + | ThrowStatement + | TryStatement + | TSAbstractClassProperty + | TSAbstractKeyword + | TSAbstractMethodDefinition + | TSAnyKeyword + | TSArrayType + | TSAsExpression + | TSAsyncKeyword + | TSBigIntKeyword + | TSBooleanKeyword + | TSCallSignatureDeclaration + | TSClassImplements + | TSConditionalType + | TSConstKeyword + | TSConstructorType + | TSConstructSignatureDeclaration + | TSDeclareFunction + | TSDeclareKeyword + | TSDefaultKeyword + | TSEnumDeclaration + | TSEnumMember + | TSExportAssignment + | TSExportKeyword + | TSExternalModuleReference + | TSFunctionType + | TSImportEqualsDeclaration + | TSImportType + | TSIndexedAccessType + | TSIndexSignature + | TSInferType + | TSInterfaceDeclaration + | TSInterfaceBody + | TSInterfaceHeritage + | TSIntersectionType + | TSLiteralType + | TSMappedType + | TSMethodSignature + | TSModuleBlock + | TSModuleDeclaration + | TSNamespaceExportDeclaration + | TSNeverKeyword + | TSNonNullExpression + | TSNullKeyword + | TSNumberKeyword + | TSObjectKeyword + | TSOptionalType + | TSParameterProperty + | TSParenthesizedType + | TSPropertySignature + | TSPublicKeyword + | TSPrivateKeyword + | TSProtectedKeyword + | TSQualifiedName + | TSReadonlyKeyword + | TSRestType + | TSStaticKeyword + | TSStringKeyword + | TSSymbolKeyword + | TSThisType + | TSTupleType + | TSTypeAliasDeclaration + | TSTypeAnnotation + | TSTypeAssertion + | TSTypeLiteral + | TSTypeOperator + | TSTypeParameter + | TSTypeParameterDeclaration + | TSTypeParameterInstantiation + | TSTypePredicate + | TSTypeQuery + | TSTypeReference + | TSUndefinedKeyword + | TSUnionType + | TSUnknownKeyword + | TSVoidKeyword + | UpdateExpression + | UnaryExpression + | VariableDeclaration + | VariableDeclarator + | WhileStatement + | WithStatement + | YieldExpression; + ////////// // Reusable Unions // These are based off of types used in the Typescript AST definitions // **Ensure you sort the union members alphabetically** ////////// -type Accessibility = 'public' | 'protected' | 'private'; -type BindingPattern = ArrayPattern | ObjectPattern; -type BindingName = BindingPattern | Identifier; -type ClassElement = +export type Accessibility = 'public' | 'protected' | 'private'; +export type BindingPattern = ArrayPattern | ObjectPattern; +export type BindingName = BindingPattern | Identifier; +export type ClassElement = | ClassProperty | FunctionExpression | MethodDefinition | TSAbstractClassProperty | TSAbstractMethodDefinition | TSIndexSignature; -type DeclarationStatement = +export type DeclarationStatement = | ClassDeclaration | ClassExpression | ExportAllDeclaration @@ -66,8 +225,18 @@ type DeclarationStatement = | TSNamespaceExportDeclaration | TSTypeAliasDeclaration | TSEnumDeclaration; -type EntityName = Identifier | TSQualifiedName; -type Expression = +export type EntityName = Identifier | TSQualifiedName; +export type ExportDeclaration = + | ClassDeclaration + | ClassExpression + | FunctionDeclaration + | TSDeclareFunction + | TSEnumDeclaration + | TSInterfaceDeclaration + | TSModuleDeclaration + | TSTypeAliasDeclaration + | VariableDeclarator; +export type Expression = | ArrowFunctionExpression | AssignmentExpression | BinaryExpression @@ -85,25 +254,30 @@ type Expression = | TSAsExpression | TSUnaryExpression | YieldExpression; -type ExpressionWithTypeArguments = TSClassImplements | TSInterfaceHeritage; -type ForInitialiser = Expression | VariableDeclaration; -type ImportClause = +export type ExpressionWithTypeArguments = + | TSClassImplements + | TSInterfaceHeritage; +export type ForInitialiser = Expression | VariableDeclaration; +export type ImportClause = | ImportDefaultSpecifier | ImportNamespaceSpecifier | ImportSpecifier; -type IterationStatement = +export type IterationStatement = | DoWhileStatement | ForInStatement | ForOfStatement | ForStatement | WhileStatement; -type JSXChild = JSXElement | JSXExpression | JSXFragment | JSXText; -type JSXExpression = +export type JSXChild = JSXElement | JSXExpression | JSXFragment | JSXText; +export type JSXExpression = | JSXEmptyExpression | JSXSpreadChild | JSXExpressionContainer; -type JSXTagNameExpression = Identifier | MemberExpression | ThisExpression; -type LeftHandSideExpression = +export type JSXTagNameExpression = + | Identifier + | MemberExpression + | ThisExpression; +export type LeftHandSideExpression = | CallExpression | ClassExpression | ClassDeclaration @@ -113,8 +287,8 @@ type LeftHandSideExpression = | PrimaryExpression | TaggedTemplateExpression | TSNonNullExpression; -type LiteralExpression = BigIntLiteral | Literal | TemplateLiteral; -type Modifier = +export type LiteralExpression = BigIntLiteral | Literal | TemplateLiteral; +export type Modifier = | TSAbstractKeyword | TSAsyncKeyword | TSConstKeyword @@ -126,14 +300,14 @@ type Modifier = | TSProtectedKeyword | TSReadonlyKeyword | TSStaticKeyword; -type ObjectLiteralElementLike = +export type ObjectLiteralElementLike = | MethodDefinition | Property | RestElement | SpreadElement | TSAbstractMethodDefinition; -type Parameter = AssignmentPattern | RestElement | TSParameterProperty; -type PrimaryExpression = +export type Parameter = AssignmentPattern | RestElement | TSParameterProperty; +export type PrimaryExpression = | ArrayExpression | ArrayPattern | ClassExpression @@ -152,8 +326,8 @@ type PrimaryExpression = | TemplateLiteral | ThisExpression | TSNullKeyword; -type PropertyName = Identifier | Literal; -type Statement = +export type PropertyName = Identifier | Literal; +export type Statement = | BlockStatement | BreakStatement | ContinueStatement @@ -172,13 +346,13 @@ type Statement = | TryStatement | VariableDeclaration | WithStatement; -type TypeElement = +export type TypeElement = | TSCallSignatureDeclaration | TSConstructSignatureDeclaration | TSIndexSignature | TSMethodSignature | TSPropertySignature; -type TypeNode = +export type TypeNode = | ThisExpression | TSAnyKeyword | TSArrayType @@ -215,7 +389,7 @@ type TypeNode = | TSUnionType | TSUnknownKeyword | TSVoidKeyword; -type TSUnaryExpression = +export type TSUnaryExpression = | AwaitExpression | LeftHandSideExpression | TSTypeAssertion @@ -438,12 +612,12 @@ export interface ExportAllDeclaration extends NodeBase { export interface ExportDefaultDeclaration extends NodeBase { type: 'ExportDefaultDeclaration'; - declaration: Expression; + declaration: ExportDeclaration; } export interface ExportNamedDeclaration extends NodeBase { type: 'ExportNamedDeclaration'; - declaration: Expression | null; + declaration: ExportDeclaration | null; specifiers: ExportSpecifier[]; source: Expression | null; } From 6d71be40e425593d637afa88fe42782a1904e817 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Wed, 30 Jan 2019 14:15:17 -0800 Subject: [PATCH 18/92] start strictly typing rules --- packages/eslint-plugin/package.json | 3 +- packages/eslint-plugin/src/RuleModule.ts | 206 ++++++++++++++++++ .../src/rules/adjacent-overload-signatures.ts | 89 ++++++-- .../eslint-plugin/src/rules/array-type.ts | 4 +- packages/eslint-plugin/src/rules/ban-types.ts | 4 +- packages/eslint-plugin/src/rules/camelcase.ts | 4 +- .../src/rules/class-name-casing.ts | 4 +- .../rules/explicit-function-return-type.ts | 4 +- .../rules/explicit-member-accessibility.ts | 4 +- .../src/rules/generic-type-naming.ts | 4 +- packages/eslint-plugin/src/rules/indent.ts | 2 +- .../src/rules/interface-name-prefix.ts | 4 +- .../src/rules/member-delimiter-style.ts | 4 +- .../eslint-plugin/src/rules/member-naming.ts | 4 +- .../src/rules/member-ordering.ts | 4 +- .../rules/no-angle-bracket-type-assertion.ts | 4 +- .../src/rules/no-array-constructor.ts | 4 +- .../src/rules/no-empty-interface.ts | 4 +- .../src/rules/no-explicit-any.ts | 4 +- .../src/rules/no-extraneous-class.ts | 4 +- .../src/rules/no-inferrable-types.ts | 4 +- .../eslint-plugin/src/rules/no-misused-new.ts | 4 +- .../eslint-plugin/src/rules/no-namespace.ts | 4 +- .../src/rules/no-non-null-assertion.ts | 4 +- .../rules/no-object-literal-type-assertion.ts | 4 +- .../src/rules/no-parameter-properties.ts | 4 +- .../eslint-plugin/src/rules/no-this-alias.ts | 4 +- .../src/rules/no-triple-slash-reference.ts | 4 +- .../eslint-plugin/src/rules/no-type-alias.ts | 4 +- .../eslint-plugin/src/rules/no-unused-vars.ts | 2 +- .../src/rules/no-use-before-define.ts | 2 +- .../src/rules/no-var-requires.ts | 4 +- .../src/rules/prefer-interface.ts | 4 +- .../src/rules/prefer-namespace-keyword.ts | 4 +- .../src/rules/restrict-plus-operands.ts | 4 +- .../src/rules/type-annotation-spacing.ts | 4 +- packages/eslint-plugin/src/util.ts | 13 +- packages/eslint-plugin/typings/eslint.d.ts | 1 + 38 files changed, 345 insertions(+), 93 deletions(-) create mode 100644 packages/eslint-plugin/src/RuleModule.ts diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 0a0a99df2a20..7d8e52d90fb8 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -33,7 +33,8 @@ "devDependencies": { "eslint": "^5.9.0", "eslint-docs": "^0.2.6", - "ts-node": "^8.0.1" + "ts-node": "^8.0.1", + "@typescript-eslint/typescript-estree": "1.1.0" }, "peerDependencies": { "eslint": ">=4.13.1 < 6", diff --git a/packages/eslint-plugin/src/RuleModule.ts b/packages/eslint-plugin/src/RuleModule.ts new file mode 100644 index 000000000000..35b82b7ef8ae --- /dev/null +++ b/packages/eslint-plugin/src/RuleModule.ts @@ -0,0 +1,206 @@ +import { TSESTree } from '@typescript-eslint/typescript-estree'; +import { ParserServices } from '@typescript-eslint/parser'; +import { AST, Linter, Rule, Scope, SourceCode } from 'eslint'; +import { JSONSchema4 } from 'json-schema'; + +/* +Redefine these types for these reasons: +1) We can better control what properties are option and what are not. +2) We have to replace definitions with our definitions which use our typescript-estree types. +3) We can better document the fields so it's easier for new contributers to understand. +*/ + +interface RuleMetaData { + /** + * True if the rule is deprecated, false otherwise + */ + deprecated?: boolean; + /** + * Documentation for the rule + */ + docs: { + /** + * The general category the rule falls within + */ + category: 'Best Practices' | 'Stylistic Issues' | 'Variables'; + /** + * Concise description of the rule + */ + description: string; + /** + * Extra information linking the rule to a tslint rule + */ + extraDescription: string[]; + /** + * The recommendation level for the rule. + * Used by the build tools to generate the recommended config. + * Set to false to not include it as a recommendation + */ + recommended: 'error' | 'warn' | false; + /** + * The URL of the rule's docs + */ + url: string; + }; + /** + * The fixer category. Omit if there is no fixer + */ + fixable?: 'code' | 'whitespace'; + /** + * A map of messages which the rule can report. + * The key is the messageId, and the string is the parameterised error string. + * See: https://eslint.org/docs/developer-guide/working-with-rules#messageids + */ + messages: { + [messageId: string]: string; + }; + /** + * The type of rule. + * - `"problem"` means the rule is identifying code that either will cause an error or may cause a confusing behavior. Developers should consider this a high priority to resolve. + * - `"suggestion"` means the rule is identifying something that could be done in a better way but no errors will occur if the code isn’t changed. + * - `"layout"` means the rule cares primarily about whitespace, semicolons, commas, and parentheses, all the parts of the program that determine how the code looks rather than how it executes. These rules work on parts of the code that aren’t specified in the AST. + */ + type: 'suggestion' | 'problem' | 'layout'; + /** + * The name of the rule this rule was replaced by, if it was deprecated. + */ + replacedBy?: string; + /** + * The options schema. Supply an empty array if there are no options. + */ + schema: JSONSchema4 | JSONSchema4[]; +} + +interface RuleListener { + // This isn't the correct signature, but it makes it easier to do custom unions within reusable listneers + // never will break someone's code unless they specifically type the function argument + [key: string]: (node: never) => void; +} + +interface RuleFixer { + insertTextAfter( + nodeOrToken: TSESTree.Node | AST.Token, + text: string + ): Rule.Fix; + + insertTextAfterRange(range: AST.Range, text: string): Rule.Fix; + + insertTextBefore( + nodeOrToken: TSESTree.Node | AST.Token, + text: string + ): Rule.Fix; + + insertTextBeforeRange(range: AST.Range, text: string): Rule.Fix; + + remove(nodeOrToken: TSESTree.Node | AST.Token): Rule.Fix; + + removeRange(range: AST.Range): Rule.Fix; + + replaceText(nodeOrToken: TSESTree.Node | AST.Token, text: string): Rule.Fix; + + replaceTextRange(range: AST.Range, text: string): Rule.Fix; +} + +interface ReportDescriptor { + /** + * The parameters for the message string associated with `messageId`. + */ + data?: { [key: string]: string }; + /** + * The fixer function. + */ + fix?(fixer: RuleFixer): null | Rule.Fix | IterableIterator; + /** + * The messageId which is being reported. + */ + messageId: string; + /** + * The Node which the report is being attached to + */ + node: TSESTree.Node; +} + +export interface RuleContext { + /** + * The rule ID. + */ + id: string; + /** + * An array of the configured options for this rule. + * This array does not include the rule severity. + */ + options: TOpts; + /** + * The shared settings from configuration. + * We do not have any shared settings in this plugin. + */ + settings: {}; + /** + * The name of the parser from configuration. + */ + parserPath: string; + /** + * The parser options configured for this run + */ + parserOptions: Linter.ParserOptions; + /** + * An object containing parser-provided services for rules + */ + parserServices?: ParserServices; + + /** + * Returns an array of the ancestors of the currently-traversed node, starting at + * the root of the AST and continuing through the direct parent of the current node. + * This array does not include the currently-traversed node itself. + */ + getAncestors(): TSESTree.Node[]; + + /** + * Returns a list of variables declared by the given node. + * This information can be used to track references to variables. + */ + getDeclaredVariables(node: TSESTree.Node): Scope.Variable[]; + + /** + * Returns the filename associated with the source. + */ + getFilename(): string; + + /** + * Returns the scope of the currently-traversed node. + * This information can be used track references to variables. + */ + getScope(): Scope.Scope; + + /** + * Returns a SourceCode object that you can use to work with the source that + * was passed to ESLint. + */ + getSourceCode(): SourceCode; + + /** + * Marks a variable with the given name in the current scope as used. + * This affects the no-unused-vars rule. + */ + markVariableAsUsed(name: string): boolean; + + /** + * Reports a problem in the code. + */ + report(descriptor: ReportDescriptor): void; +} + +interface RuleModule { + /** + * Metadata about the rule + */ + meta: RuleMetaData; + + /** + * Function which returns an object with methods that ESLint calls to “visit” + * nodes while traversing the abstract syntax tree. + */ + create(context: RuleContext): RuleListener; +} + +export default RuleModule; diff --git a/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts b/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts index 032fa8cf6dac..1b9f24ea34e7 100644 --- a/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts +++ b/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts @@ -3,19 +3,22 @@ * @author Patricio Trevino */ -import { Rule } from 'eslint'; +import { TSESTree } from '@typescript-eslint/typescript-estree'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -const rule: Rule.RuleModule = { +type Member = TSESTree.ClassElement | TSESTree.Statement | TSESTree.TypeElement; + +const rule: RuleModule = { meta: { type: 'suggestion', docs: { description: 'Require that member overloads be consecutive', - category: 'TypeScript', + category: 'Best Practices', extraDescription: [util.tslintRule('adjacent-overload-signatures')], url: util.metaDocsUrl('adjacent-overload-signatures'), recommended: 'error' @@ -26,36 +29,44 @@ const rule: Rule.RuleModule = { } }, - create(context: Rule.RuleContext) { + create(context) { //---------------------------------------------------------------------- // Helpers //---------------------------------------------------------------------- /** * Gets the name of the member being processed. - * @param {ASTNode} member the member being processed. + * @param member the member being processed. * @returns the name of the member or null if it's a member not relevant to the rule. */ - function getMemberName(member): string | null { - if (!member) return null; + function getMemberName(member: TSESTree.Node): string | null { + if (!member) { + return null; + } switch (member.type) { case 'ExportDefaultDeclaration': case 'ExportNamedDeclaration': { // export statements (e.g. export { a };) // have no declarations, so ignore them - return member.declaration ? getMemberName(member.declaration) : null; + if (!member.declaration) { + return null; + } + + return getMemberName(member.declaration); } case 'TSDeclareFunction': - case 'FunctionDeclaration': - case 'TSNamespaceFunctionDeclaration': { + case 'FunctionDeclaration': { return member.id && member.id.name; } case 'TSMethodSignature': { - return ( - (member.key && (member.key.name || member.key.value)) || - (member.name && (member.name.name || member.name.value)) - ); + if (member.key.type === 'Identifier') { + return member.key.name; + } else if (member.key.type === 'Literal') { + return member.key.value; + } + + return null; } case 'TSCallSignatureDeclaration': { return 'call'; @@ -64,20 +75,54 @@ const rule: Rule.RuleModule = { return 'new'; } case 'MethodDefinition': { - return member.key.name || member.key.value; - } - default: { + if (member.key.type === 'Identifier') { + return member.key.name; + } else if (member.key.type === 'Literal') { + return member.key.value; + } + return null; } } + + return null; + } + + function getMembers( + node: + | TSESTree.ClassBody + | TSESTree.Program + | TSESTree.TSModuleBlock + | TSESTree.TSTypeLiteral + | TSESTree.TSInterfaceBody + ): Member[] { + switch (node.type) { + case 'ClassBody': + case 'Program': + case 'TSModuleBlock': + case 'TSInterfaceBody': + return node.body; + + case 'TSTypeLiteral': + return node.members; + } + + return []; } /** * Check the body for overload methods. * @param {ASTNode} node the body to be inspected. */ - function checkBodyForOverloadMethods(node): void { - const members = node.body || node.members; + function checkBodyForOverloadMethods( + node: + | TSESTree.ClassBody + | TSESTree.Program + | TSESTree.TSModuleBlock + | TSESTree.TSTypeLiteral + | TSESTree.TSInterfaceBody + ): void { + const members = getMembers(node); if (members) { let lastName: string | null; @@ -112,11 +157,11 @@ const rule: Rule.RuleModule = { // Public //---------------------------------------------------------------------- return { + ClassBody: checkBodyForOverloadMethods, + Program: checkBodyForOverloadMethods, TSModuleBlock: checkBodyForOverloadMethods, TSTypeLiteral: checkBodyForOverloadMethods, - TSInterfaceBody: checkBodyForOverloadMethods, - ClassBody: checkBodyForOverloadMethods, - Program: checkBodyForOverloadMethods + TSInterfaceBody: checkBodyForOverloadMethods }; } }; diff --git a/packages/eslint-plugin/src/rules/array-type.ts b/packages/eslint-plugin/src/rules/array-type.ts index be0eb0cb6c89..ce4367df5add 100644 --- a/packages/eslint-plugin/src/rules/array-type.ts +++ b/packages/eslint-plugin/src/rules/array-type.ts @@ -4,7 +4,7 @@ * @author Armano */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; /** @@ -77,7 +77,7 @@ function typeNeedsParentheses(node): boolean { const defaultOptions = ['array']; -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { diff --git a/packages/eslint-plugin/src/rules/ban-types.ts b/packages/eslint-plugin/src/rules/ban-types.ts index b218b989e995..206d957c7bb9 100644 --- a/packages/eslint-plugin/src/rules/ban-types.ts +++ b/packages/eslint-plugin/src/rules/ban-types.ts @@ -3,7 +3,7 @@ * @author Armano */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ @@ -46,7 +46,7 @@ const defaultOptions: Options[] = [ } ]; -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { diff --git a/packages/eslint-plugin/src/rules/camelcase.ts b/packages/eslint-plugin/src/rules/camelcase.ts index e14eaaa2ce49..714ca269972c 100644 --- a/packages/eslint-plugin/src/rules/camelcase.ts +++ b/packages/eslint-plugin/src/rules/camelcase.ts @@ -3,7 +3,7 @@ * @author Patricio Trevino */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import baseRule from 'eslint/lib/rules/camelcase'; import * as util from '../util'; @@ -19,7 +19,7 @@ const defaultOptions = [ ]; /* eslint-disable eslint-plugin/require-meta-type */ -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: Object.assign({}, baseRule.meta, { docs: { description: 'Enforce camelCase naming convention', diff --git a/packages/eslint-plugin/src/rules/class-name-casing.ts b/packages/eslint-plugin/src/rules/class-name-casing.ts index 2316f1390f17..a2635118a349 100644 --- a/packages/eslint-plugin/src/rules/class-name-casing.ts +++ b/packages/eslint-plugin/src/rules/class-name-casing.ts @@ -4,14 +4,14 @@ * @author Armano */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { diff --git a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts index 558100b98842..98d765312c5f 100644 --- a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts +++ b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts @@ -3,7 +3,7 @@ * @author Scott O'Hara */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ @@ -16,7 +16,7 @@ const defaultOptions = [ } ]; -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'problem', docs: { diff --git a/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts index c3ceb793855a..9e91b5041fd0 100644 --- a/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts +++ b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts @@ -3,14 +3,14 @@ * @author Danny Fritz */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'problem', docs: { diff --git a/packages/eslint-plugin/src/rules/generic-type-naming.ts b/packages/eslint-plugin/src/rules/generic-type-naming.ts index 77cda5898c7a..f3cd7cffef02 100644 --- a/packages/eslint-plugin/src/rules/generic-type-naming.ts +++ b/packages/eslint-plugin/src/rules/generic-type-naming.ts @@ -2,7 +2,7 @@ * @fileoverview Enforces naming of generic type variables. */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; const defaultOptions = [ @@ -10,7 +10,7 @@ const defaultOptions = [ '^T([A-Z0-9][a-zA-Z0-9]*){0,1}$' ]; -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { diff --git a/packages/eslint-plugin/src/rules/indent.ts b/packages/eslint-plugin/src/rules/indent.ts index 496cff0f36e5..3c51eeac9658 100644 --- a/packages/eslint-plugin/src/rules/indent.ts +++ b/packages/eslint-plugin/src/rules/indent.ts @@ -3,7 +3,7 @@ * @author Patricio Trevino */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import baseRule from 'eslint/lib/rules/indent'; import * as util from '../util'; diff --git a/packages/eslint-plugin/src/rules/interface-name-prefix.ts b/packages/eslint-plugin/src/rules/interface-name-prefix.ts index a6c03a675c8d..101a0eb63eeb 100644 --- a/packages/eslint-plugin/src/rules/interface-name-prefix.ts +++ b/packages/eslint-plugin/src/rules/interface-name-prefix.ts @@ -3,7 +3,7 @@ * @author Danny Fritz */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ @@ -12,7 +12,7 @@ import * as util from '../util'; const defaultOptions = ['never']; -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { diff --git a/packages/eslint-plugin/src/rules/member-delimiter-style.ts b/packages/eslint-plugin/src/rules/member-delimiter-style.ts index b27360f0f768..c89ae9788106 100644 --- a/packages/eslint-plugin/src/rules/member-delimiter-style.ts +++ b/packages/eslint-plugin/src/rules/member-delimiter-style.ts @@ -4,7 +4,7 @@ * @author Brad Zacher */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ @@ -65,7 +65,7 @@ const definition = { additionalProperties: false }; -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { diff --git a/packages/eslint-plugin/src/rules/member-naming.ts b/packages/eslint-plugin/src/rules/member-naming.ts index 8f8134ddc08c..5e717cc1c1e0 100644 --- a/packages/eslint-plugin/src/rules/member-naming.ts +++ b/packages/eslint-plugin/src/rules/member-naming.ts @@ -3,7 +3,7 @@ * @author Ian MacLeod */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ @@ -19,7 +19,7 @@ type Modifiers = keyof Options; const defaultOptions: Options[] = [{}]; -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { diff --git a/packages/eslint-plugin/src/rules/member-ordering.ts b/packages/eslint-plugin/src/rules/member-ordering.ts index c995a12634cf..c60649051b99 100644 --- a/packages/eslint-plugin/src/rules/member-ordering.ts +++ b/packages/eslint-plugin/src/rules/member-ordering.ts @@ -3,7 +3,7 @@ * @author Patricio Trevino */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ @@ -82,7 +82,7 @@ const defaultOptions: Options[] = [ } ]; -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { diff --git a/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts b/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts index 04d28d341e84..706f6b9af4b6 100644 --- a/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts @@ -3,14 +3,14 @@ * @author Patricio Trevino */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'problem', docs: { diff --git a/packages/eslint-plugin/src/rules/no-array-constructor.ts b/packages/eslint-plugin/src/rules/no-array-constructor.ts index 9b0e2ded4a07..512bd6a820c8 100644 --- a/packages/eslint-plugin/src/rules/no-array-constructor.ts +++ b/packages/eslint-plugin/src/rules/no-array-constructor.ts @@ -4,14 +4,14 @@ * @author Matt DuVall */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { diff --git a/packages/eslint-plugin/src/rules/no-empty-interface.ts b/packages/eslint-plugin/src/rules/no-empty-interface.ts index 44af962bfe8f..1a1e9b325c28 100644 --- a/packages/eslint-plugin/src/rules/no-empty-interface.ts +++ b/packages/eslint-plugin/src/rules/no-empty-interface.ts @@ -3,14 +3,14 @@ * @author Patricio Trevino */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { diff --git a/packages/eslint-plugin/src/rules/no-explicit-any.ts b/packages/eslint-plugin/src/rules/no-explicit-any.ts index 19fd06b22f13..0514274f282c 100644 --- a/packages/eslint-plugin/src/rules/no-explicit-any.ts +++ b/packages/eslint-plugin/src/rules/no-explicit-any.ts @@ -4,14 +4,14 @@ * @author Patricio Trevino */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { diff --git a/packages/eslint-plugin/src/rules/no-extraneous-class.ts b/packages/eslint-plugin/src/rules/no-extraneous-class.ts index 53ad3932dbb1..09deca824761 100644 --- a/packages/eslint-plugin/src/rules/no-extraneous-class.ts +++ b/packages/eslint-plugin/src/rules/no-extraneous-class.ts @@ -3,7 +3,7 @@ * @author Jed Fox */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ @@ -18,7 +18,7 @@ const defaultOptions = [ } ]; -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { diff --git a/packages/eslint-plugin/src/rules/no-inferrable-types.ts b/packages/eslint-plugin/src/rules/no-inferrable-types.ts index 1224c8167e02..a3d06971decb 100644 --- a/packages/eslint-plugin/src/rules/no-inferrable-types.ts +++ b/packages/eslint-plugin/src/rules/no-inferrable-types.ts @@ -3,7 +3,7 @@ * @author James Garbutt */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ @@ -17,7 +17,7 @@ const defaultOptions = [ } ]; -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { diff --git a/packages/eslint-plugin/src/rules/no-misused-new.ts b/packages/eslint-plugin/src/rules/no-misused-new.ts index 51eb76d6cd1a..ac4c36d24f0d 100644 --- a/packages/eslint-plugin/src/rules/no-misused-new.ts +++ b/packages/eslint-plugin/src/rules/no-misused-new.ts @@ -3,14 +3,14 @@ * @author Armano */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'problem', docs: { diff --git a/packages/eslint-plugin/src/rules/no-namespace.ts b/packages/eslint-plugin/src/rules/no-namespace.ts index 411375cf7d06..ad1f4bd73aa3 100644 --- a/packages/eslint-plugin/src/rules/no-namespace.ts +++ b/packages/eslint-plugin/src/rules/no-namespace.ts @@ -3,7 +3,7 @@ * @author Patricio Trevino */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ @@ -17,7 +17,7 @@ const defaultOptions = [ } ]; -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { diff --git a/packages/eslint-plugin/src/rules/no-non-null-assertion.ts b/packages/eslint-plugin/src/rules/no-non-null-assertion.ts index 8c0dccd2c7ab..26b0ef099a9b 100644 --- a/packages/eslint-plugin/src/rules/no-non-null-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-non-null-assertion.ts @@ -3,14 +3,14 @@ * @author Macklin Underdown */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'problem', docs: { diff --git a/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts b/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts index 57de65a995cf..3007ba14477b 100644 --- a/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts @@ -3,7 +3,7 @@ * @author Armano */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ @@ -16,7 +16,7 @@ const defaultOptions = [ } ]; -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'problem', docs: { diff --git a/packages/eslint-plugin/src/rules/no-parameter-properties.ts b/packages/eslint-plugin/src/rules/no-parameter-properties.ts index 3c8e8325f3d9..7a68382d915d 100644 --- a/packages/eslint-plugin/src/rules/no-parameter-properties.ts +++ b/packages/eslint-plugin/src/rules/no-parameter-properties.ts @@ -3,7 +3,7 @@ * @author Patricio Trevino */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ @@ -16,7 +16,7 @@ const defaultOptions = [ } ]; -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'problem', docs: { diff --git a/packages/eslint-plugin/src/rules/no-this-alias.ts b/packages/eslint-plugin/src/rules/no-this-alias.ts index ab4cf1d7dc77..dc28d33f3dbf 100644 --- a/packages/eslint-plugin/src/rules/no-this-alias.ts +++ b/packages/eslint-plugin/src/rules/no-this-alias.ts @@ -3,7 +3,7 @@ * @author Jed Fox */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ @@ -17,7 +17,7 @@ const defaultOptions = [ } ]; -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { diff --git a/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts b/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts index 9409005f0456..7cf01ba530ee 100644 --- a/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts +++ b/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts @@ -3,14 +3,14 @@ * @author Danny Fritz */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { diff --git a/packages/eslint-plugin/src/rules/no-type-alias.ts b/packages/eslint-plugin/src/rules/no-type-alias.ts index 26e11c4b058d..30a343dd4003 100644 --- a/packages/eslint-plugin/src/rules/no-type-alias.ts +++ b/packages/eslint-plugin/src/rules/no-type-alias.ts @@ -3,7 +3,7 @@ * @author Patricio Trevino */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ @@ -19,7 +19,7 @@ const defaultOptions = [ } ]; -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { diff --git a/packages/eslint-plugin/src/rules/no-unused-vars.ts b/packages/eslint-plugin/src/rules/no-unused-vars.ts index ed92fbebfb9a..7676d0b06081 100644 --- a/packages/eslint-plugin/src/rules/no-unused-vars.ts +++ b/packages/eslint-plugin/src/rules/no-unused-vars.ts @@ -3,7 +3,7 @@ * @author James Henry */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import baseRule from 'eslint/lib/rules/no-unused-vars'; import { Identifier } from 'estree'; import * as util from '../util'; diff --git a/packages/eslint-plugin/src/rules/no-use-before-define.ts b/packages/eslint-plugin/src/rules/no-use-before-define.ts index 975c58c9fe07..09c13cc1b6a4 100644 --- a/packages/eslint-plugin/src/rules/no-use-before-define.ts +++ b/packages/eslint-plugin/src/rules/no-use-before-define.ts @@ -195,7 +195,7 @@ const defaultOptions = [ } ]; -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'problem', docs: { diff --git a/packages/eslint-plugin/src/rules/no-var-requires.ts b/packages/eslint-plugin/src/rules/no-var-requires.ts index 305a1545ed68..ea52cea26cc3 100644 --- a/packages/eslint-plugin/src/rules/no-var-requires.ts +++ b/packages/eslint-plugin/src/rules/no-var-requires.ts @@ -3,14 +3,14 @@ * @author Macklin Underdown */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'problem', docs: { diff --git a/packages/eslint-plugin/src/rules/prefer-interface.ts b/packages/eslint-plugin/src/rules/prefer-interface.ts index 9fb45a0671d5..322d3f3986d4 100644 --- a/packages/eslint-plugin/src/rules/prefer-interface.ts +++ b/packages/eslint-plugin/src/rules/prefer-interface.ts @@ -3,14 +3,14 @@ * @author Armano */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { diff --git a/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts b/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts index 9864e215b93c..5f99225cec90 100644 --- a/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts +++ b/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts @@ -4,14 +4,14 @@ * @author Armano */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { diff --git a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts index 5a422e98ff91..339c4cc6b08f 100644 --- a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts +++ b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts @@ -4,7 +4,7 @@ * @author Armano */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import ts from 'typescript'; import * as util from '../util'; @@ -12,7 +12,7 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'problem', docs: { diff --git a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts index 4819e63b26af..68626c68179b 100644 --- a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts +++ b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts @@ -4,7 +4,7 @@ * @author Patricio Trevino */ -import { Rule } from 'eslint'; +import RuleModule from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ @@ -26,7 +26,7 @@ const defaultOptions = [ {} ]; -const rule: Rule.RuleModule = { +const rule: RuleModule = { meta: { type: 'layout', docs: { diff --git a/packages/eslint-plugin/src/util.ts b/packages/eslint-plugin/src/util.ts index ad14422dee23..c81ae20c256f 100644 --- a/packages/eslint-plugin/src/util.ts +++ b/packages/eslint-plugin/src/util.ts @@ -1,5 +1,6 @@ -import { Rule } from 'eslint'; -import { ParserServices } from '@typescript-eslint/typescript-estree'; +import { ParserServices } from '@typescript-eslint/parser'; + +import { RuleContext } from './RuleModule'; // note - cannot migrate this to an import statement because it will make TSC copy the package.json to the dist folder const version = require('../package.json').version; @@ -118,8 +119,6 @@ export function applyDefault( /** * Upper cases the first character or the string - * @param str a string - * @returns upper case first */ export function upperCaseFirst(str: string) { return str[0].toUpperCase() + str.slice(1); @@ -127,10 +126,10 @@ export function upperCaseFirst(str: string) { /** * Try to retrieve typescript parser service from context - * @param {RuleContext} context Rule context - * @returns {{esTreeNodeToTSNodeMap}|{program}|Object|*} parserServices */ -export function getParserServices(context: Rule.RuleContext): ParserServices { +export function getParserServices( + context: RuleContext +): ParserServices { if ( !context.parserServices || !context.parserServices.program || diff --git a/packages/eslint-plugin/typings/eslint.d.ts b/packages/eslint-plugin/typings/eslint.d.ts index 4cccafbfb7e6..db9b8e18ddd5 100644 --- a/packages/eslint-plugin/typings/eslint.d.ts +++ b/packages/eslint-plugin/typings/eslint.d.ts @@ -2,6 +2,7 @@ // module augmentation is weird import { RuleTester, Scope } from 'eslint'; +import { TSESTree } from '@typescript-eslint/typescript-estree'; declare module 'eslint' { namespace Scope { interface Variable { From a690933e445bf800015b9b1f336a1868f08c61ad Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Wed, 30 Jan 2019 17:35:50 -0800 Subject: [PATCH 19/92] fix incorrect type for TSTypeRef --- packages/typescript-estree/src/typedefs.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/typescript-estree/src/typedefs.ts b/packages/typescript-estree/src/typedefs.ts index 62e764a0a221..ae3db0bf7bd1 100644 --- a/packages/typescript-estree/src/typedefs.ts +++ b/packages/typescript-estree/src/typedefs.ts @@ -1,4 +1,4 @@ -interface LineAndColumnData { +export interface LineAndColumnData { /** * Line number (1-indexed) */ @@ -934,7 +934,7 @@ export interface TSAnyKeyword extends NodeBase { } export interface TSArrayType extends NodeBase { - type: 'TSTSArrayType'; + type: 'TSArrayType'; elementType: TypeNode; } @@ -1307,7 +1307,7 @@ export interface TSTypeQuery extends NodeBase { export interface TSTypeReference extends NodeBase { type: 'TSTypeReference'; typeName: EntityName; - typeParameters: TSTypeParameterInstantiation; + typeParameters: TSTypeParameterInstantiation | undefined; } export interface TSUndefinedKeyword extends NodeBase { From 9796d0fdb7cd07828770ac8a2918b4f6675dcec2 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Wed, 30 Jan 2019 17:36:30 -0800 Subject: [PATCH 20/92] find+replace remove create(context: Rule.RuleContext) --- packages/eslint-plugin/src/rules/ban-types.ts | 2 +- packages/eslint-plugin/src/rules/camelcase.ts | 2 +- packages/eslint-plugin/src/rules/class-name-casing.ts | 2 +- .../eslint-plugin/src/rules/explicit-function-return-type.ts | 2 +- .../eslint-plugin/src/rules/explicit-member-accessibility.ts | 2 +- packages/eslint-plugin/src/rules/generic-type-naming.ts | 2 +- packages/eslint-plugin/src/rules/indent.ts | 2 +- packages/eslint-plugin/src/rules/interface-name-prefix.ts | 2 +- packages/eslint-plugin/src/rules/member-delimiter-style.ts | 2 +- packages/eslint-plugin/src/rules/member-naming.ts | 2 +- packages/eslint-plugin/src/rules/member-ordering.ts | 2 +- .../eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts | 2 +- packages/eslint-plugin/src/rules/no-array-constructor.ts | 2 +- packages/eslint-plugin/src/rules/no-empty-interface.ts | 2 +- packages/eslint-plugin/src/rules/no-explicit-any.ts | 2 +- packages/eslint-plugin/src/rules/no-extraneous-class.ts | 2 +- packages/eslint-plugin/src/rules/no-inferrable-types.ts | 2 +- packages/eslint-plugin/src/rules/no-misused-new.ts | 2 +- packages/eslint-plugin/src/rules/no-namespace.ts | 2 +- packages/eslint-plugin/src/rules/no-non-null-assertion.ts | 2 +- .../eslint-plugin/src/rules/no-object-literal-type-assertion.ts | 2 +- packages/eslint-plugin/src/rules/no-parameter-properties.ts | 2 +- packages/eslint-plugin/src/rules/no-this-alias.ts | 2 +- packages/eslint-plugin/src/rules/no-triple-slash-reference.ts | 2 +- packages/eslint-plugin/src/rules/no-type-alias.ts | 2 +- packages/eslint-plugin/src/rules/no-unused-vars.ts | 2 +- packages/eslint-plugin/src/rules/no-use-before-define.ts | 2 +- packages/eslint-plugin/src/rules/no-var-requires.ts | 2 +- packages/eslint-plugin/src/rules/prefer-interface.ts | 2 +- packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts | 2 +- packages/eslint-plugin/src/rules/restrict-plus-operands.ts | 2 +- packages/eslint-plugin/src/rules/type-annotation-spacing.ts | 2 +- 32 files changed, 32 insertions(+), 32 deletions(-) diff --git a/packages/eslint-plugin/src/rules/ban-types.ts b/packages/eslint-plugin/src/rules/ban-types.ts index 206d957c7bb9..5ec55924e5c1 100644 --- a/packages/eslint-plugin/src/rules/ban-types.ts +++ b/packages/eslint-plugin/src/rules/ban-types.ts @@ -87,7 +87,7 @@ const rule: RuleModule = { ] }, - create(context: Rule.RuleContext) { + create(context) { const banedTypes = util.applyDefault(defaultOptions, context.options)[0] .types; diff --git a/packages/eslint-plugin/src/rules/camelcase.ts b/packages/eslint-plugin/src/rules/camelcase.ts index 714ca269972c..6b5dfce864f3 100644 --- a/packages/eslint-plugin/src/rules/camelcase.ts +++ b/packages/eslint-plugin/src/rules/camelcase.ts @@ -28,7 +28,7 @@ const rule: RuleModule = { } }), - create(context: Rule.RuleContext) { + create(context) { const rules = baseRule.create(context); const TS_PROPERTY_TYPES = [ 'TSPropertySignature', diff --git a/packages/eslint-plugin/src/rules/class-name-casing.ts b/packages/eslint-plugin/src/rules/class-name-casing.ts index a2635118a349..42e500246bbd 100644 --- a/packages/eslint-plugin/src/rules/class-name-casing.ts +++ b/packages/eslint-plugin/src/rules/class-name-casing.ts @@ -24,7 +24,7 @@ const rule: RuleModule = { schema: [] }, - create(context: Rule.RuleContext) { + create(context) { // variables should be defined here //---------------------------------------------------------------------- diff --git a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts index 98d765312c5f..76e88bb32a57 100644 --- a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts +++ b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts @@ -39,7 +39,7 @@ const rule: RuleModule = { ] }, - create(context: Rule.RuleContext) { + create(context) { const options = util.applyDefault(defaultOptions, context.options)[0]; //---------------------------------------------------------------------- diff --git a/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts index 9e91b5041fd0..8a943a2ab7e8 100644 --- a/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts +++ b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts @@ -24,7 +24,7 @@ const rule: RuleModule = { schema: [] }, - create(context: Rule.RuleContext) { + create(context) { //---------------------------------------------------------------------- // Helpers //---------------------------------------------------------------------- diff --git a/packages/eslint-plugin/src/rules/generic-type-naming.ts b/packages/eslint-plugin/src/rules/generic-type-naming.ts index f3cd7cffef02..acd5448db0ac 100644 --- a/packages/eslint-plugin/src/rules/generic-type-naming.ts +++ b/packages/eslint-plugin/src/rules/generic-type-naming.ts @@ -29,7 +29,7 @@ const rule: RuleModule = { recommended: 'error' }, - create(context: Rule.RuleContext) { + create(context) { const rule = util.applyDefault(defaultOptions, context.options)[0]; const regex = new RegExp(rule); diff --git a/packages/eslint-plugin/src/rules/indent.ts b/packages/eslint-plugin/src/rules/indent.ts index 3c51eeac9658..5b8eecae03b6 100644 --- a/packages/eslint-plugin/src/rules/indent.ts +++ b/packages/eslint-plugin/src/rules/indent.ts @@ -105,7 +105,7 @@ const rule: Rule.RuleModule = Object.assign({}, baseRule, { messages: baseRule.meta!.messages }, - create(context: Rule.RuleContext) { + create(context) { // because we extend the base rule, have to update opts on the context // the context defines options as readonly though... const contextWithDefaults: Rule.RuleContext = Object.create(context, { diff --git a/packages/eslint-plugin/src/rules/interface-name-prefix.ts b/packages/eslint-plugin/src/rules/interface-name-prefix.ts index 101a0eb63eeb..fe00a5f723fb 100644 --- a/packages/eslint-plugin/src/rules/interface-name-prefix.ts +++ b/packages/eslint-plugin/src/rules/interface-name-prefix.ts @@ -29,7 +29,7 @@ const rule: RuleModule = { ] }, - create(context: Rule.RuleContext) { + create(context) { const option = util.applyDefault(defaultOptions, context.options)[0]; const never = option !== 'always'; diff --git a/packages/eslint-plugin/src/rules/member-delimiter-style.ts b/packages/eslint-plugin/src/rules/member-delimiter-style.ts index c89ae9788106..51059a348f3b 100644 --- a/packages/eslint-plugin/src/rules/member-delimiter-style.ts +++ b/packages/eslint-plugin/src/rules/member-delimiter-style.ts @@ -100,7 +100,7 @@ const rule: RuleModule = { ] }, - create(context: Rule.RuleContext) { + create(context) { const sourceCode = context.getSourceCode(); const options = util.applyDefault(defaultOptions, context.options)[0]; diff --git a/packages/eslint-plugin/src/rules/member-naming.ts b/packages/eslint-plugin/src/rules/member-naming.ts index 5e717cc1c1e0..20eec2576ed0 100644 --- a/packages/eslint-plugin/src/rules/member-naming.ts +++ b/packages/eslint-plugin/src/rules/member-naming.ts @@ -55,7 +55,7 @@ const rule: RuleModule = { ] }, - create(context: Rule.RuleContext) { + create(context) { const config = util.applyDefault(defaultOptions, context.options)[0]; const conventions = (Object.keys(config) as Modifiers[]).reduce>( (acc, accessibility) => { diff --git a/packages/eslint-plugin/src/rules/member-ordering.ts b/packages/eslint-plugin/src/rules/member-ordering.ts index c60649051b99..6ab793f57821 100644 --- a/packages/eslint-plugin/src/rules/member-ordering.ts +++ b/packages/eslint-plugin/src/rules/member-ordering.ts @@ -167,7 +167,7 @@ const rule: RuleModule = { ] }, - create(context: Rule.RuleContext) { + create(context) { const options = util.applyDefault(defaultOptions, context.options)[0]; const functionExpressions = [ diff --git a/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts b/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts index 706f6b9af4b6..c59d8b93c2d3 100644 --- a/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts @@ -24,7 +24,7 @@ const rule: RuleModule = { schema: [] }, - create(context: Rule.RuleContext) { + create(context) { const sourceCode = context.getSourceCode(); //---------------------------------------------------------------------- diff --git a/packages/eslint-plugin/src/rules/no-array-constructor.ts b/packages/eslint-plugin/src/rules/no-array-constructor.ts index 512bd6a820c8..0fdfc5e5d84f 100644 --- a/packages/eslint-plugin/src/rules/no-array-constructor.ts +++ b/packages/eslint-plugin/src/rules/no-array-constructor.ts @@ -24,7 +24,7 @@ const rule: RuleModule = { schema: [] }, - create(context: Rule.RuleContext) { + create(context) { /** * Disallow construction of dense arrays using the Array constructor * @param {ASTNode} node node to evaluate diff --git a/packages/eslint-plugin/src/rules/no-empty-interface.ts b/packages/eslint-plugin/src/rules/no-empty-interface.ts index 1a1e9b325c28..bfda506c63a2 100644 --- a/packages/eslint-plugin/src/rules/no-empty-interface.ts +++ b/packages/eslint-plugin/src/rules/no-empty-interface.ts @@ -27,7 +27,7 @@ const rule: RuleModule = { // Public //---------------------------------------------------------------------- - create(context: Rule.RuleContext) { + create(context) { return { TSInterfaceDeclaration(node) { if (node.body.body.length !== 0) { diff --git a/packages/eslint-plugin/src/rules/no-explicit-any.ts b/packages/eslint-plugin/src/rules/no-explicit-any.ts index 0514274f282c..2e6e8a8149ae 100644 --- a/packages/eslint-plugin/src/rules/no-explicit-any.ts +++ b/packages/eslint-plugin/src/rules/no-explicit-any.ts @@ -24,7 +24,7 @@ const rule: RuleModule = { schema: [] }, - create(context: Rule.RuleContext) { + create(context) { return { TSAnyKeyword(node) { context.report({ diff --git a/packages/eslint-plugin/src/rules/no-extraneous-class.ts b/packages/eslint-plugin/src/rules/no-extraneous-class.ts index 09deca824761..9987b6dccbb5 100644 --- a/packages/eslint-plugin/src/rules/no-extraneous-class.ts +++ b/packages/eslint-plugin/src/rules/no-extraneous-class.ts @@ -53,7 +53,7 @@ const rule: RuleModule = { } }, - create(context: Rule.RuleContext) { + create(context) { const { allowConstructorOnly, allowEmpty, diff --git a/packages/eslint-plugin/src/rules/no-inferrable-types.ts b/packages/eslint-plugin/src/rules/no-inferrable-types.ts index a3d06971decb..dd37514f71f0 100644 --- a/packages/eslint-plugin/src/rules/no-inferrable-types.ts +++ b/packages/eslint-plugin/src/rules/no-inferrable-types.ts @@ -45,7 +45,7 @@ const rule: RuleModule = { ] }, - create(context: Rule.RuleContext) { + create(context) { const { ignoreParameters, ignoreProperties } = util.applyDefault( defaultOptions, context.options diff --git a/packages/eslint-plugin/src/rules/no-misused-new.ts b/packages/eslint-plugin/src/rules/no-misused-new.ts index ac4c36d24f0d..0b407ffc9943 100644 --- a/packages/eslint-plugin/src/rules/no-misused-new.ts +++ b/packages/eslint-plugin/src/rules/no-misused-new.ts @@ -31,7 +31,7 @@ const rule: RuleModule = { // Public //---------------------------------------------------------------------- - create(context: Rule.RuleContext) { + create(context) { /** * @param {ASTNode} node type to be inspected. * @returns name of simple type or null diff --git a/packages/eslint-plugin/src/rules/no-namespace.ts b/packages/eslint-plugin/src/rules/no-namespace.ts index ad1f4bd73aa3..81106aebbcf6 100644 --- a/packages/eslint-plugin/src/rules/no-namespace.ts +++ b/packages/eslint-plugin/src/rules/no-namespace.ts @@ -48,7 +48,7 @@ const rule: RuleModule = { ] }, - create(context: Rule.RuleContext) { + create(context) { const { allowDeclarations, allowDefinitionFiles } = util.applyDefault( defaultOptions, context.options diff --git a/packages/eslint-plugin/src/rules/no-non-null-assertion.ts b/packages/eslint-plugin/src/rules/no-non-null-assertion.ts index 26b0ef099a9b..53e28d161bf0 100644 --- a/packages/eslint-plugin/src/rules/no-non-null-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-non-null-assertion.ts @@ -23,7 +23,7 @@ const rule: RuleModule = { }, schema: [] }, - create(context: Rule.RuleContext) { + create(context) { //---------------------------------------------------------------------- // Public //---------------------------------------------------------------------- diff --git a/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts b/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts index 3007ba14477b..6dccf8df300b 100644 --- a/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts @@ -43,7 +43,7 @@ const rule: RuleModule = { } ] }, - create(context: Rule.RuleContext) { + create(context) { const { allowAsParameter } = util.applyDefault( defaultOptions, context.options diff --git a/packages/eslint-plugin/src/rules/no-parameter-properties.ts b/packages/eslint-plugin/src/rules/no-parameter-properties.ts index 7a68382d915d..aa74b0d5d9c3 100644 --- a/packages/eslint-plugin/src/rules/no-parameter-properties.ts +++ b/packages/eslint-plugin/src/rules/no-parameter-properties.ts @@ -52,7 +52,7 @@ const rule: RuleModule = { ] }, - create(context: Rule.RuleContext) { + create(context) { const { allows } = util.applyDefault(defaultOptions, context.options)[0]; //---------------------------------------------------------------------- diff --git a/packages/eslint-plugin/src/rules/no-this-alias.ts b/packages/eslint-plugin/src/rules/no-this-alias.ts index dc28d33f3dbf..d1847c0be366 100644 --- a/packages/eslint-plugin/src/rules/no-this-alias.ts +++ b/packages/eslint-plugin/src/rules/no-this-alias.ts @@ -52,7 +52,7 @@ const rule: RuleModule = { } }, - create(context: Rule.RuleContext) { + create(context) { const { allowDestructuring, allowedNames } = util.applyDefault( defaultOptions, context.options diff --git a/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts b/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts index 7cf01ba530ee..91dcb051058a 100644 --- a/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts +++ b/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts @@ -26,7 +26,7 @@ const rule: RuleModule = { } }, - create(context: Rule.RuleContext) { + create(context) { const referenceRegExp = /^\/\s*']; const sourceCode = context.getSourceCode(); const options = util.applyDefault(defaultOptions, context.options)[0]; From 4f8a9d160c98ab196ed30aa60f2b85b12aae6ef3 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Wed, 30 Jan 2019 17:36:50 -0800 Subject: [PATCH 21/92] Bring SourceCode type internally --- packages/eslint-plugin/src/RuleModule.ts | 197 ++++++++++++++++++++++- 1 file changed, 194 insertions(+), 3 deletions(-) diff --git a/packages/eslint-plugin/src/RuleModule.ts b/packages/eslint-plugin/src/RuleModule.ts index 35b82b7ef8ae..dd487d539e60 100644 --- a/packages/eslint-plugin/src/RuleModule.ts +++ b/packages/eslint-plugin/src/RuleModule.ts @@ -1,6 +1,7 @@ import { TSESTree } from '@typescript-eslint/typescript-estree'; import { ParserServices } from '@typescript-eslint/parser'; -import { AST, Linter, Rule, Scope, SourceCode } from 'eslint'; +import { AST, Linter, Rule, Scope } from 'eslint'; +import { Comment as ESTreeComment } from 'estree'; import { JSONSchema4 } from 'json-schema'; /* @@ -10,6 +11,193 @@ Redefine these types for these reasons: 3) We can better document the fields so it's easier for new contributers to understand. */ +//#region SourceCode + +// eslint-disable-next-line @typescript-eslint/no-namespace +namespace SourceCode { + export interface Config { + text: string; + ast: AST.Program; + parserServices?: ParserServices; + scopeManager?: Scope.ScopeManager; + visitorKeys?: VisitorKeys; + } + + export interface VisitorKeys { + [nodeType: string]: string[]; + } + + export type FilterPredicate = ( + tokenOrComment: AST.Token | ESTreeComment + ) => boolean; + + export type CursorWithSkipOptions = + | number + | FilterPredicate + | { + includeComments?: boolean; + filter?: FilterPredicate; + skip?: number; + }; + + export type CursorWithCountOptions = + | number + | FilterPredicate + | { + includeComments?: boolean; + filter?: FilterPredicate; + count?: number; + }; +} + +// eslint-disable-next-line no-redeclare +declare class SourceCode { + text: string; + ast: AST.Program; + lines: string[]; + hasBOM: boolean; + parserServices: ParserServices; + scopeManager: Scope.ScopeManager; + visitorKeys: SourceCode.VisitorKeys; + + constructor(text: string, ast: AST.Program); + // eslint-disable-next-line no-dupe-class-members + constructor(config: SourceCode.Config); + + static splitLines(text: string): string[]; + + getText( + node?: TSESTree.Node, + beforeCount?: number, + afterCount?: number + ): string; + + getLines(): string[]; + + getAllComments(): ESTreeComment[]; + + getComments( + node: TSESTree.Node + ): { leading: ESTreeComment[]; trailing: ESTreeComment[] }; + + getJSDocComment(node: TSESTree.Node): AST.Token | null; + + getNodeByRangeIndex(index: number): TSESTree.Node | null; + + isSpaceBetweenTokens(first: AST.Token, second: AST.Token): boolean; + + getLocFromIndex(index: number): TSESTree.LineAndColumnData; + + getIndexFromLoc(location: TSESTree.LineAndColumnData): number; + + // Inherited methods from TokenStore + // --------------------------------- + + getTokenByRangeStart( + offset: number, + options?: { includeComments?: boolean } + ): AST.Token | null; + + getFirstToken( + node: TSESTree.Node, + options?: SourceCode.CursorWithSkipOptions + ): AST.Token | null; + + getFirstTokens( + node: TSESTree.Node, + options?: SourceCode.CursorWithCountOptions + ): AST.Token[]; + + getLastToken( + node: TSESTree.Node, + options?: SourceCode.CursorWithSkipOptions + ): AST.Token | null; + + getLastTokens( + node: TSESTree.Node, + options?: SourceCode.CursorWithCountOptions + ): AST.Token[]; + + getTokenBefore( + node: TSESTree.Node | AST.Token | ESTreeComment, + options?: SourceCode.CursorWithSkipOptions + ): AST.Token | null; + + getTokensBefore( + node: TSESTree.Node | AST.Token | ESTreeComment, + options?: SourceCode.CursorWithCountOptions + ): AST.Token[]; + + getTokenAfter( + node: TSESTree.Node | AST.Token | ESTreeComment, + options?: SourceCode.CursorWithSkipOptions + ): AST.Token | null; + + getTokensAfter( + node: TSESTree.Node | AST.Token | ESTreeComment, + options?: SourceCode.CursorWithCountOptions + ): AST.Token[]; + + getFirstTokenBetween( + left: TSESTree.Node | AST.Token | ESTreeComment, + right: TSESTree.Node | AST.Token | ESTreeComment, + options?: SourceCode.CursorWithSkipOptions + ): AST.Token | null; + + getFirstTokensBetween( + left: TSESTree.Node | AST.Token | ESTreeComment, + right: TSESTree.Node | AST.Token | ESTreeComment, + options?: SourceCode.CursorWithCountOptions + ): AST.Token[]; + + getLastTokenBetween( + left: TSESTree.Node | AST.Token | ESTreeComment, + right: TSESTree.Node | AST.Token | ESTreeComment, + options?: SourceCode.CursorWithSkipOptions + ): AST.Token | null; + + getLastTokensBetween( + left: TSESTree.Node | AST.Token | ESTreeComment, + right: TSESTree.Node | AST.Token | ESTreeComment, + options?: SourceCode.CursorWithCountOptions + ): AST.Token[]; + + getTokensBetween( + left: TSESTree.Node | AST.Token | ESTreeComment, + right: TSESTree.Node | AST.Token | ESTreeComment, + padding?: + | number + | SourceCode.FilterPredicate + | SourceCode.CursorWithCountOptions + ): AST.Token[]; + + getTokens( + node: TSESTree.Node, + beforeCount?: number, + afterCount?: number + ): AST.Token[]; + // eslint-disable-next-line no-dupe-class-members + getTokens( + node: TSESTree.Node, + options: SourceCode.FilterPredicate | SourceCode.CursorWithCountOptions + ): AST.Token[]; + + commentsExistBetween( + left: TSESTree.Node | AST.Token, + right: TSESTree.Node | AST.Token + ): boolean; + + getCommentsBefore(nodeOrToken: TSESTree.Node | AST.Token): ESTreeComment[]; + + getCommentsAfter(nodeOrToken: TSESTree.Node | AST.Token): ESTreeComment[]; + + getCommentsInside(node: TSESTree.Node): ESTreeComment[]; +} + +//#endregion SourceCode + +//#region Rule + interface RuleMetaData { /** * True if the rule is deprecated, false otherwise @@ -109,7 +297,7 @@ interface ReportDescriptor { /** * The fixer function. */ - fix?(fixer: RuleFixer): null | Rule.Fix | IterableIterator; + fix?(fixer: RuleFixer): null | Rule.Fix | Rule.Fix[]; /** * The messageId which is being reported. */ @@ -120,7 +308,7 @@ interface ReportDescriptor { node: TSESTree.Node; } -export interface RuleContext { +interface RuleContext { /** * The rule ID. */ @@ -203,4 +391,7 @@ interface RuleModule { create(context: RuleContext): RuleListener; } +//#endregion Rule + +export { RuleContext }; export default RuleModule; From b76a2d7b6a79f6bedff72e5df1833d9e4dd87b5b Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Wed, 30 Jan 2019 17:37:16 -0800 Subject: [PATCH 22/92] adjacent-overload-signatures --- .../src/rules/adjacent-overload-signatures.ts | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts b/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts index 1b9f24ea34e7..e380bea9b2f3 100644 --- a/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts +++ b/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts @@ -11,6 +11,12 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ +type RuleNode = + | TSESTree.ClassBody + | TSESTree.Program + | TSESTree.TSModuleBlock + | TSESTree.TSTypeLiteral + | TSESTree.TSInterfaceBody; type Member = TSESTree.ClassElement | TSESTree.Statement | TSESTree.TypeElement; const rule: RuleModule = { @@ -88,14 +94,7 @@ const rule: RuleModule = { return null; } - function getMembers( - node: - | TSESTree.ClassBody - | TSESTree.Program - | TSESTree.TSModuleBlock - | TSESTree.TSTypeLiteral - | TSESTree.TSInterfaceBody - ): Member[] { + function getMembers(node: RuleNode): Member[] { switch (node.type) { case 'ClassBody': case 'Program': @@ -114,14 +113,7 @@ const rule: RuleModule = { * Check the body for overload methods. * @param {ASTNode} node the body to be inspected. */ - function checkBodyForOverloadMethods( - node: - | TSESTree.ClassBody - | TSESTree.Program - | TSESTree.TSModuleBlock - | TSESTree.TSTypeLiteral - | TSESTree.TSInterfaceBody - ): void { + function checkBodyForOverloadMethods(node: RuleNode): void { const members = getMembers(node); if (members) { From 5826ca2482901b6627f8e773f3d36a30909c34dc Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Wed, 30 Jan 2019 17:37:28 -0800 Subject: [PATCH 23/92] array-type --- .../eslint-plugin/src/rules/array-type.ts | 42 +++++++++++-------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/packages/eslint-plugin/src/rules/array-type.ts b/packages/eslint-plugin/src/rules/array-type.ts index ce4367df5add..99ad3f656407 100644 --- a/packages/eslint-plugin/src/rules/array-type.ts +++ b/packages/eslint-plugin/src/rules/array-type.ts @@ -4,14 +4,15 @@ * @author Armano */ +import { TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from '../RuleModule'; import * as util from '../util'; /** * Check whatever node can be considered as simple - * @param {ASTNode} node the node to be evaluated. + * @param node the node to be evaluated. */ -function isSimpleType(node): boolean { +function isSimpleType(node: TSESTree.Node): boolean { switch (node.type) { case 'Identifier': case 'TSAnyKeyword': @@ -55,9 +56,9 @@ function isSimpleType(node): boolean { /** * Check if node needs parentheses - * @param {ASTNode} node the node to be evaluated. + * @param node the node to be evaluated. */ -function typeNeedsParentheses(node): boolean { +function typeNeedsParentheses(node: TSESTree.Node): boolean { switch (node.type) { case 'TSTypeReference': return typeNeedsParentheses(node.typeName); @@ -83,7 +84,7 @@ const rule: RuleModule = { docs: { description: 'Requires using either `T[]` or `Array` for arrays', extraDescription: [util.tslintRule('array-type')], - category: 'TypeScript', + category: 'Stylistic Issues', url: util.metaDocsUrl('array-type'), recommended: 'error' }, @@ -104,16 +105,19 @@ const rule: RuleModule = { } ] }, - create(context: Rule.RuleContext) { + create(context) { const option = util.applyDefault(defaultOptions, context.options)[0]; const sourceCode = context.getSourceCode(); /** * Check if whitespace is needed before this node - * @param {ASTNode} node the node to be evaluated. + * @param node the node to be evaluated. */ - function requireWhitespaceBefore(node): boolean { + function requireWhitespaceBefore(node: TSESTree.Node): boolean { const prevToken = sourceCode.getTokenBefore(node); + if (!prevToken) { + return false; + } if (node.range[0] - prevToken.range[1] > 0) { return false; @@ -123,9 +127,9 @@ const rule: RuleModule = { } /** - * @param {ASTNode} node the node to be evaluated. + * @param node the node to be evaluated. */ - function getMessageType(node): string { + function getMessageType(node: TSESTree.Node): string { if (node) { if (node.type === 'TSParenthesizedType') { return getMessageType(node.typeAnnotation); @@ -142,7 +146,7 @@ const rule: RuleModule = { //---------------------------------------------------------------------- return { - TSArrayType(node) { + TSArrayType(node: TSESTree.TSArrayType) { if ( option === 'array' || (option === 'array-simple' && isSimpleType(node.elementType)) @@ -168,19 +172,21 @@ const rule: RuleModule = { ]; if (node.elementType.type === 'TSParenthesizedType') { - toFix.push( - fixer.remove(sourceCode.getFirstToken(node.elementType)) - ); - toFix.push( - fixer.remove(sourceCode.getLastToken(node.elementType)) - ); + const first = sourceCode.getFirstToken(node.elementType); + const last = sourceCode.getLastToken(node.elementType); + if (!first || !last) { + return null; + } + + toFix.push(fixer.remove(first)); + toFix.push(fixer.remove(last)); } return toFix; } }); }, - TSTypeReference(node) { + TSTypeReference(node: TSESTree.TSTypeReference) { if ( option === 'generic' || node.typeName.type !== 'Identifier' || From e18ad839585dec8d3ecec006ea9c2089acae9ab5 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Wed, 30 Jan 2019 17:46:46 -0800 Subject: [PATCH 24/92] ban-types --- packages/eslint-plugin/src/RuleModule.ts | 29 +++++++---- packages/eslint-plugin/src/rules/ban-types.ts | 28 +++++----- .../eslint-plugin/tests/rules/ban-types.ts | 52 +++++++++---------- packages/eslint-plugin/typings/eslint.d.ts | 8 ++- packages/typescript-estree/src/typedefs.ts | 4 ++ 5 files changed, 70 insertions(+), 51 deletions(-) diff --git a/packages/eslint-plugin/src/RuleModule.ts b/packages/eslint-plugin/src/RuleModule.ts index dd487d539e60..d08bb268cd64 100644 --- a/packages/eslint-plugin/src/RuleModule.ts +++ b/packages/eslint-plugin/src/RuleModule.ts @@ -1,6 +1,6 @@ import { TSESTree } from '@typescript-eslint/typescript-estree'; import { ParserServices } from '@typescript-eslint/parser'; -import { AST, Linter, Rule, Scope } from 'eslint'; +import { AST, Linter, Scope } from 'eslint'; import { Comment as ESTreeComment } from 'estree'; import { JSONSchema4 } from 'json-schema'; @@ -265,30 +265,37 @@ interface RuleListener { [key: string]: (node: never) => void; } +interface RuleFix { + range: AST.Range; + text: string; +} + interface RuleFixer { insertTextAfter( nodeOrToken: TSESTree.Node | AST.Token, text: string - ): Rule.Fix; + ): RuleFix; - insertTextAfterRange(range: AST.Range, text: string): Rule.Fix; + insertTextAfterRange(range: AST.Range, text: string): RuleFix; insertTextBefore( nodeOrToken: TSESTree.Node | AST.Token, text: string - ): Rule.Fix; + ): RuleFix; - insertTextBeforeRange(range: AST.Range, text: string): Rule.Fix; + insertTextBeforeRange(range: AST.Range, text: string): RuleFix; - remove(nodeOrToken: TSESTree.Node | AST.Token): Rule.Fix; + remove(nodeOrToken: TSESTree.Node | AST.Token): RuleFix; - removeRange(range: AST.Range): Rule.Fix; + removeRange(range: AST.Range): RuleFix; - replaceText(nodeOrToken: TSESTree.Node | AST.Token, text: string): Rule.Fix; + replaceText(nodeOrToken: TSESTree.Node | AST.Token, text: string): RuleFix; - replaceTextRange(range: AST.Range, text: string): Rule.Fix; + replaceTextRange(range: AST.Range, text: string): RuleFix; } +type ReportFixFunction = (fixer: RuleFixer) => null | RuleFix | RuleFix[]; + interface ReportDescriptor { /** * The parameters for the message string associated with `messageId`. @@ -297,7 +304,7 @@ interface ReportDescriptor { /** * The fixer function. */ - fix?(fixer: RuleFixer): null | Rule.Fix | Rule.Fix[]; + fix?: ReportFixFunction | null; /** * The messageId which is being reported. */ @@ -393,5 +400,5 @@ interface RuleModule { //#endregion Rule -export { RuleContext }; +export { RuleContext, ReportFixFunction }; export default RuleModule; diff --git a/packages/eslint-plugin/src/rules/ban-types.ts b/packages/eslint-plugin/src/rules/ban-types.ts index 5ec55924e5c1..e5a3bbc0567e 100644 --- a/packages/eslint-plugin/src/rules/ban-types.ts +++ b/packages/eslint-plugin/src/rules/ban-types.ts @@ -3,7 +3,8 @@ * @author Armano */ -import RuleModule from '../RuleModule'; +import { TSESTree } from '@typescript-eslint/typescript-estree'; +import RuleModule, { ReportFixFunction } from '../RuleModule'; import * as util from '../util'; //------------------------------------------------------------------------------ @@ -13,10 +14,12 @@ import * as util from '../util'; interface Options { types: Record< string, - { - message: string; - fixWith?: string; - } + | string + | null + | { + message: string; + fixWith?: string; + } >; } const defaultOptions: Options[] = [ @@ -46,13 +49,13 @@ const defaultOptions: Options[] = [ } ]; -const rule: RuleModule = { +const rule: RuleModule<[Options]> = { meta: { type: 'suggestion', docs: { description: 'Enforces that types will not to be used', extraDescription: [util.tslintRule('ban-types')], - category: 'TypeScript', + category: 'Best Practices', url: util.metaDocsUrl('ban-types'), recommended: 'error' }, @@ -96,12 +99,13 @@ const rule: RuleModule = { //---------------------------------------------------------------------- return { - 'TSTypeReference Identifier'(node) { + 'TSTypeReference Identifier'(node: TSESTree.Identifier) { if (node.parent && node.parent.type !== 'TSQualifiedName') { if (node.name in banedTypes) { let customMessage = ''; const bannedCfgValue = banedTypes[node.name]; - let fixWith: string | null = null; + + let fix: ReportFixFunction | null = null; if (typeof bannedCfgValue === 'string') { customMessage += ` ${bannedCfgValue}`; @@ -110,7 +114,8 @@ const rule: RuleModule = { customMessage += ` ${bannedCfgValue.message}`; } if (bannedCfgValue.fixWith) { - fixWith = bannedCfgValue.fixWith; + const fixWith = bannedCfgValue.fixWith; + fix = fixer => fixer.replaceText(node, fixWith); } } @@ -121,8 +126,7 @@ const rule: RuleModule = { name: node.name, customMessage }, - fix: - fixWith !== null && (fixer => fixer.replaceText(node, fixWith)) + fix }); } } diff --git a/packages/eslint-plugin/tests/rules/ban-types.ts b/packages/eslint-plugin/tests/rules/ban-types.ts index 3655e9feb10d..c5726d4e597c 100644 --- a/packages/eslint-plugin/tests/rules/ban-types.ts +++ b/packages/eslint-plugin/tests/rules/ban-types.ts @@ -130,24 +130,22 @@ ruleTester.run('ban-types', rule, { }, { code: ` - class Foo extends Bar implements Baz { - constructor (foo: String | Object) { - } +class Foo extends Bar implements Baz { + constructor (foo: String | Object) {} - exit () : Array { - const foo: String = 1 as String - } - } + exit() : Array { + const foo: String = 1 as String + } +} `, output: ` - class Foo extends Bar implements Baz { - constructor (foo: string | Object) { - } +class Foo extends Bar implements Baz { + constructor (foo: string | Object) {} - exit () : Array { - const foo: string = 1 as string - } - } + exit() : Array { + const foo: string = 1 as string + } +} `, errors: [ { @@ -157,7 +155,7 @@ ruleTester.run('ban-types', rule, { customMessage: ' Use string instead.' }, line: 2, - column: 27 + column: 15 }, { messageId: 'bannedTypeMessage', @@ -166,7 +164,7 @@ ruleTester.run('ban-types', rule, { customMessage: ' Use string instead.' }, line: 2, - column: 47 + column: 35 }, { messageId: 'bannedTypeMessage', @@ -175,7 +173,7 @@ ruleTester.run('ban-types', rule, { customMessage: " Use '{}' instead." }, line: 2, - column: 70 + column: 58 }, { messageId: 'bannedTypeMessage', @@ -184,7 +182,7 @@ ruleTester.run('ban-types', rule, { customMessage: ' Use string instead.' }, line: 3, - column: 35 + column: 21 }, { messageId: 'bannedTypeMessage', @@ -193,13 +191,13 @@ ruleTester.run('ban-types', rule, { customMessage: " Use '{}' instead." }, line: 3, - column: 44 + column: 30 }, { messageId: 'bannedTypeMessage', data: { name: 'Array', customMessage: '' }, - line: 6, - column: 27 + line: 5, + column: 12 }, { messageId: 'bannedTypeMessage', @@ -207,8 +205,8 @@ ruleTester.run('ban-types', rule, { name: 'String', customMessage: ' Use string instead.' }, - line: 6, - column: 33 + line: 5, + column: 18 }, { messageId: 'bannedTypeMessage', @@ -216,8 +214,8 @@ ruleTester.run('ban-types', rule, { name: 'String', customMessage: ' Use string instead.' }, - line: 7, - column: 32 + line: 6, + column: 16 }, { messageId: 'bannedTypeMessage', @@ -225,8 +223,8 @@ ruleTester.run('ban-types', rule, { name: 'String', customMessage: ' Use string instead.' }, - line: 7, - column: 46 + line: 6, + column: 30 } ], options diff --git a/packages/eslint-plugin/typings/eslint.d.ts b/packages/eslint-plugin/typings/eslint.d.ts index db9b8e18ddd5..1205bc5f0140 100644 --- a/packages/eslint-plugin/typings/eslint.d.ts +++ b/packages/eslint-plugin/typings/eslint.d.ts @@ -3,6 +3,7 @@ // module augmentation is weird import { RuleTester, Scope } from 'eslint'; import { TSESTree } from '@typescript-eslint/typescript-estree'; +import RuleModule from '../src/RuleModule'; declare module 'eslint' { namespace Scope { interface Variable { @@ -16,6 +17,11 @@ declare module 'eslint' { invalid: RuleTester.InvalidTestCase[]; } interface RuleTester { - run(name: string, rule: Rule.RuleModule, tests: RuleTesterRunTests): void; + run( + name: string, + // have to keep the base eslint def for our base eslint-rule test cases + rule: RuleModule | Rule.RuleModule, + tests: RuleTesterRunTests + ): void; } } diff --git a/packages/typescript-estree/src/typedefs.ts b/packages/typescript-estree/src/typedefs.ts index ae3db0bf7bd1..b5b00b7a85a8 100644 --- a/packages/typescript-estree/src/typedefs.ts +++ b/packages/typescript-estree/src/typedefs.ts @@ -29,6 +29,10 @@ interface NodeBase { * The first is the start position of the node, the second is the end position of the node. */ range: [number, number]; + /** + * The parent node of the current node + */ + parent?: Node; // every node *will* have a type, but let the nodes define their own exact string // type: string; From c5875f61d295367c325f82b847d8c141fe200018 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Thu, 31 Jan 2019 08:59:22 -0800 Subject: [PATCH 25/92] move the eslint retyping to a fake module --- packages/eslint-plugin/src/RuleModule.ts | 404 ----------------- .../src/rules/adjacent-overload-signatures.ts | 2 +- .../eslint-plugin/src/rules/array-type.ts | 2 +- packages/eslint-plugin/src/rules/ban-types.ts | 5 +- .../src/rules/class-name-casing.ts | 2 +- .../rules/explicit-function-return-type.ts | 2 +- .../rules/explicit-member-accessibility.ts | 2 +- .../src/rules/generic-type-naming.ts | 2 +- packages/eslint-plugin/src/rules/indent.ts | 2 +- .../src/rules/interface-name-prefix.ts | 2 +- .../src/rules/member-delimiter-style.ts | 2 +- .../eslint-plugin/src/rules/member-naming.ts | 2 +- .../src/rules/member-ordering.ts | 2 +- .../rules/no-angle-bracket-type-assertion.ts | 2 +- .../src/rules/no-array-constructor.ts | 2 +- .../src/rules/no-empty-interface.ts | 2 +- .../src/rules/no-explicit-any.ts | 2 +- .../src/rules/no-extraneous-class.ts | 2 +- .../src/rules/no-inferrable-types.ts | 2 +- .../eslint-plugin/src/rules/no-misused-new.ts | 2 +- .../eslint-plugin/src/rules/no-namespace.ts | 2 +- .../src/rules/no-non-null-assertion.ts | 2 +- .../rules/no-object-literal-type-assertion.ts | 2 +- .../src/rules/no-parameter-properties.ts | 2 +- .../eslint-plugin/src/rules/no-this-alias.ts | 2 +- .../src/rules/no-triple-slash-reference.ts | 2 +- .../eslint-plugin/src/rules/no-type-alias.ts | 2 +- .../eslint-plugin/src/rules/no-unused-vars.ts | 2 +- .../src/rules/no-var-requires.ts | 2 +- .../src/rules/prefer-interface.ts | 2 +- .../src/rules/prefer-namespace-keyword.ts | 2 +- .../src/rules/restrict-plus-operands.ts | 2 +- .../src/rules/type-annotation-spacing.ts | 2 +- .../eslint-plugin/tests/rules/array-type.ts | 30 +- .../eslint-plugin/typings/eslint-rules.d.ts | 8 +- packages/eslint-plugin/typings/eslint.d.ts | 3 +- packages/eslint-plugin/typings/ts-eslint.d.ts | 408 ++++++++++++++++++ 37 files changed, 460 insertions(+), 460 deletions(-) delete mode 100644 packages/eslint-plugin/src/RuleModule.ts create mode 100644 packages/eslint-plugin/typings/ts-eslint.d.ts diff --git a/packages/eslint-plugin/src/RuleModule.ts b/packages/eslint-plugin/src/RuleModule.ts deleted file mode 100644 index d08bb268cd64..000000000000 --- a/packages/eslint-plugin/src/RuleModule.ts +++ /dev/null @@ -1,404 +0,0 @@ -import { TSESTree } from '@typescript-eslint/typescript-estree'; -import { ParserServices } from '@typescript-eslint/parser'; -import { AST, Linter, Scope } from 'eslint'; -import { Comment as ESTreeComment } from 'estree'; -import { JSONSchema4 } from 'json-schema'; - -/* -Redefine these types for these reasons: -1) We can better control what properties are option and what are not. -2) We have to replace definitions with our definitions which use our typescript-estree types. -3) We can better document the fields so it's easier for new contributers to understand. -*/ - -//#region SourceCode - -// eslint-disable-next-line @typescript-eslint/no-namespace -namespace SourceCode { - export interface Config { - text: string; - ast: AST.Program; - parserServices?: ParserServices; - scopeManager?: Scope.ScopeManager; - visitorKeys?: VisitorKeys; - } - - export interface VisitorKeys { - [nodeType: string]: string[]; - } - - export type FilterPredicate = ( - tokenOrComment: AST.Token | ESTreeComment - ) => boolean; - - export type CursorWithSkipOptions = - | number - | FilterPredicate - | { - includeComments?: boolean; - filter?: FilterPredicate; - skip?: number; - }; - - export type CursorWithCountOptions = - | number - | FilterPredicate - | { - includeComments?: boolean; - filter?: FilterPredicate; - count?: number; - }; -} - -// eslint-disable-next-line no-redeclare -declare class SourceCode { - text: string; - ast: AST.Program; - lines: string[]; - hasBOM: boolean; - parserServices: ParserServices; - scopeManager: Scope.ScopeManager; - visitorKeys: SourceCode.VisitorKeys; - - constructor(text: string, ast: AST.Program); - // eslint-disable-next-line no-dupe-class-members - constructor(config: SourceCode.Config); - - static splitLines(text: string): string[]; - - getText( - node?: TSESTree.Node, - beforeCount?: number, - afterCount?: number - ): string; - - getLines(): string[]; - - getAllComments(): ESTreeComment[]; - - getComments( - node: TSESTree.Node - ): { leading: ESTreeComment[]; trailing: ESTreeComment[] }; - - getJSDocComment(node: TSESTree.Node): AST.Token | null; - - getNodeByRangeIndex(index: number): TSESTree.Node | null; - - isSpaceBetweenTokens(first: AST.Token, second: AST.Token): boolean; - - getLocFromIndex(index: number): TSESTree.LineAndColumnData; - - getIndexFromLoc(location: TSESTree.LineAndColumnData): number; - - // Inherited methods from TokenStore - // --------------------------------- - - getTokenByRangeStart( - offset: number, - options?: { includeComments?: boolean } - ): AST.Token | null; - - getFirstToken( - node: TSESTree.Node, - options?: SourceCode.CursorWithSkipOptions - ): AST.Token | null; - - getFirstTokens( - node: TSESTree.Node, - options?: SourceCode.CursorWithCountOptions - ): AST.Token[]; - - getLastToken( - node: TSESTree.Node, - options?: SourceCode.CursorWithSkipOptions - ): AST.Token | null; - - getLastTokens( - node: TSESTree.Node, - options?: SourceCode.CursorWithCountOptions - ): AST.Token[]; - - getTokenBefore( - node: TSESTree.Node | AST.Token | ESTreeComment, - options?: SourceCode.CursorWithSkipOptions - ): AST.Token | null; - - getTokensBefore( - node: TSESTree.Node | AST.Token | ESTreeComment, - options?: SourceCode.CursorWithCountOptions - ): AST.Token[]; - - getTokenAfter( - node: TSESTree.Node | AST.Token | ESTreeComment, - options?: SourceCode.CursorWithSkipOptions - ): AST.Token | null; - - getTokensAfter( - node: TSESTree.Node | AST.Token | ESTreeComment, - options?: SourceCode.CursorWithCountOptions - ): AST.Token[]; - - getFirstTokenBetween( - left: TSESTree.Node | AST.Token | ESTreeComment, - right: TSESTree.Node | AST.Token | ESTreeComment, - options?: SourceCode.CursorWithSkipOptions - ): AST.Token | null; - - getFirstTokensBetween( - left: TSESTree.Node | AST.Token | ESTreeComment, - right: TSESTree.Node | AST.Token | ESTreeComment, - options?: SourceCode.CursorWithCountOptions - ): AST.Token[]; - - getLastTokenBetween( - left: TSESTree.Node | AST.Token | ESTreeComment, - right: TSESTree.Node | AST.Token | ESTreeComment, - options?: SourceCode.CursorWithSkipOptions - ): AST.Token | null; - - getLastTokensBetween( - left: TSESTree.Node | AST.Token | ESTreeComment, - right: TSESTree.Node | AST.Token | ESTreeComment, - options?: SourceCode.CursorWithCountOptions - ): AST.Token[]; - - getTokensBetween( - left: TSESTree.Node | AST.Token | ESTreeComment, - right: TSESTree.Node | AST.Token | ESTreeComment, - padding?: - | number - | SourceCode.FilterPredicate - | SourceCode.CursorWithCountOptions - ): AST.Token[]; - - getTokens( - node: TSESTree.Node, - beforeCount?: number, - afterCount?: number - ): AST.Token[]; - // eslint-disable-next-line no-dupe-class-members - getTokens( - node: TSESTree.Node, - options: SourceCode.FilterPredicate | SourceCode.CursorWithCountOptions - ): AST.Token[]; - - commentsExistBetween( - left: TSESTree.Node | AST.Token, - right: TSESTree.Node | AST.Token - ): boolean; - - getCommentsBefore(nodeOrToken: TSESTree.Node | AST.Token): ESTreeComment[]; - - getCommentsAfter(nodeOrToken: TSESTree.Node | AST.Token): ESTreeComment[]; - - getCommentsInside(node: TSESTree.Node): ESTreeComment[]; -} - -//#endregion SourceCode - -//#region Rule - -interface RuleMetaData { - /** - * True if the rule is deprecated, false otherwise - */ - deprecated?: boolean; - /** - * Documentation for the rule - */ - docs: { - /** - * The general category the rule falls within - */ - category: 'Best Practices' | 'Stylistic Issues' | 'Variables'; - /** - * Concise description of the rule - */ - description: string; - /** - * Extra information linking the rule to a tslint rule - */ - extraDescription: string[]; - /** - * The recommendation level for the rule. - * Used by the build tools to generate the recommended config. - * Set to false to not include it as a recommendation - */ - recommended: 'error' | 'warn' | false; - /** - * The URL of the rule's docs - */ - url: string; - }; - /** - * The fixer category. Omit if there is no fixer - */ - fixable?: 'code' | 'whitespace'; - /** - * A map of messages which the rule can report. - * The key is the messageId, and the string is the parameterised error string. - * See: https://eslint.org/docs/developer-guide/working-with-rules#messageids - */ - messages: { - [messageId: string]: string; - }; - /** - * The type of rule. - * - `"problem"` means the rule is identifying code that either will cause an error or may cause a confusing behavior. Developers should consider this a high priority to resolve. - * - `"suggestion"` means the rule is identifying something that could be done in a better way but no errors will occur if the code isn’t changed. - * - `"layout"` means the rule cares primarily about whitespace, semicolons, commas, and parentheses, all the parts of the program that determine how the code looks rather than how it executes. These rules work on parts of the code that aren’t specified in the AST. - */ - type: 'suggestion' | 'problem' | 'layout'; - /** - * The name of the rule this rule was replaced by, if it was deprecated. - */ - replacedBy?: string; - /** - * The options schema. Supply an empty array if there are no options. - */ - schema: JSONSchema4 | JSONSchema4[]; -} - -interface RuleListener { - // This isn't the correct signature, but it makes it easier to do custom unions within reusable listneers - // never will break someone's code unless they specifically type the function argument - [key: string]: (node: never) => void; -} - -interface RuleFix { - range: AST.Range; - text: string; -} - -interface RuleFixer { - insertTextAfter( - nodeOrToken: TSESTree.Node | AST.Token, - text: string - ): RuleFix; - - insertTextAfterRange(range: AST.Range, text: string): RuleFix; - - insertTextBefore( - nodeOrToken: TSESTree.Node | AST.Token, - text: string - ): RuleFix; - - insertTextBeforeRange(range: AST.Range, text: string): RuleFix; - - remove(nodeOrToken: TSESTree.Node | AST.Token): RuleFix; - - removeRange(range: AST.Range): RuleFix; - - replaceText(nodeOrToken: TSESTree.Node | AST.Token, text: string): RuleFix; - - replaceTextRange(range: AST.Range, text: string): RuleFix; -} - -type ReportFixFunction = (fixer: RuleFixer) => null | RuleFix | RuleFix[]; - -interface ReportDescriptor { - /** - * The parameters for the message string associated with `messageId`. - */ - data?: { [key: string]: string }; - /** - * The fixer function. - */ - fix?: ReportFixFunction | null; - /** - * The messageId which is being reported. - */ - messageId: string; - /** - * The Node which the report is being attached to - */ - node: TSESTree.Node; -} - -interface RuleContext { - /** - * The rule ID. - */ - id: string; - /** - * An array of the configured options for this rule. - * This array does not include the rule severity. - */ - options: TOpts; - /** - * The shared settings from configuration. - * We do not have any shared settings in this plugin. - */ - settings: {}; - /** - * The name of the parser from configuration. - */ - parserPath: string; - /** - * The parser options configured for this run - */ - parserOptions: Linter.ParserOptions; - /** - * An object containing parser-provided services for rules - */ - parserServices?: ParserServices; - - /** - * Returns an array of the ancestors of the currently-traversed node, starting at - * the root of the AST and continuing through the direct parent of the current node. - * This array does not include the currently-traversed node itself. - */ - getAncestors(): TSESTree.Node[]; - - /** - * Returns a list of variables declared by the given node. - * This information can be used to track references to variables. - */ - getDeclaredVariables(node: TSESTree.Node): Scope.Variable[]; - - /** - * Returns the filename associated with the source. - */ - getFilename(): string; - - /** - * Returns the scope of the currently-traversed node. - * This information can be used track references to variables. - */ - getScope(): Scope.Scope; - - /** - * Returns a SourceCode object that you can use to work with the source that - * was passed to ESLint. - */ - getSourceCode(): SourceCode; - - /** - * Marks a variable with the given name in the current scope as used. - * This affects the no-unused-vars rule. - */ - markVariableAsUsed(name: string): boolean; - - /** - * Reports a problem in the code. - */ - report(descriptor: ReportDescriptor): void; -} - -interface RuleModule { - /** - * Metadata about the rule - */ - meta: RuleMetaData; - - /** - * Function which returns an object with methods that ESLint calls to “visit” - * nodes while traversing the abstract syntax tree. - */ - create(context: RuleContext): RuleListener; -} - -//#endregion Rule - -export { RuleContext, ReportFixFunction }; -export default RuleModule; diff --git a/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts b/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts index e380bea9b2f3..0e87fcaebb0a 100644 --- a/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts +++ b/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts @@ -4,7 +4,7 @@ */ import { TSESTree } from '@typescript-eslint/typescript-estree'; -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/array-type.ts b/packages/eslint-plugin/src/rules/array-type.ts index 99ad3f656407..e3ddc8e765f1 100644 --- a/packages/eslint-plugin/src/rules/array-type.ts +++ b/packages/eslint-plugin/src/rules/array-type.ts @@ -5,7 +5,7 @@ */ import { TSESTree } from '@typescript-eslint/typescript-estree'; -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; /** diff --git a/packages/eslint-plugin/src/rules/ban-types.ts b/packages/eslint-plugin/src/rules/ban-types.ts index e5a3bbc0567e..f7696b19d81c 100644 --- a/packages/eslint-plugin/src/rules/ban-types.ts +++ b/packages/eslint-plugin/src/rules/ban-types.ts @@ -4,7 +4,7 @@ */ import { TSESTree } from '@typescript-eslint/typescript-estree'; -import RuleModule, { ReportFixFunction } from '../RuleModule'; +import RuleModule, { ReportFixFunction } from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ @@ -22,7 +22,8 @@ interface Options { } >; } -const defaultOptions: Options[] = [ + +const defaultOptions: [Options] = [ { types: { String: { diff --git a/packages/eslint-plugin/src/rules/class-name-casing.ts b/packages/eslint-plugin/src/rules/class-name-casing.ts index 42e500246bbd..f9cc12f46993 100644 --- a/packages/eslint-plugin/src/rules/class-name-casing.ts +++ b/packages/eslint-plugin/src/rules/class-name-casing.ts @@ -4,7 +4,7 @@ * @author Armano */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts index 76e88bb32a57..318026d70afd 100644 --- a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts +++ b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts @@ -3,7 +3,7 @@ * @author Scott O'Hara */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts index 8a943a2ab7e8..df73a897edd0 100644 --- a/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts +++ b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts @@ -3,7 +3,7 @@ * @author Danny Fritz */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/generic-type-naming.ts b/packages/eslint-plugin/src/rules/generic-type-naming.ts index acd5448db0ac..e0de2968173c 100644 --- a/packages/eslint-plugin/src/rules/generic-type-naming.ts +++ b/packages/eslint-plugin/src/rules/generic-type-naming.ts @@ -2,7 +2,7 @@ * @fileoverview Enforces naming of generic type variables. */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; const defaultOptions = [ diff --git a/packages/eslint-plugin/src/rules/indent.ts b/packages/eslint-plugin/src/rules/indent.ts index 5b8eecae03b6..ffd2665127fd 100644 --- a/packages/eslint-plugin/src/rules/indent.ts +++ b/packages/eslint-plugin/src/rules/indent.ts @@ -3,7 +3,7 @@ * @author Patricio Trevino */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import baseRule from 'eslint/lib/rules/indent'; import * as util from '../util'; diff --git a/packages/eslint-plugin/src/rules/interface-name-prefix.ts b/packages/eslint-plugin/src/rules/interface-name-prefix.ts index fe00a5f723fb..ef23f1f027b3 100644 --- a/packages/eslint-plugin/src/rules/interface-name-prefix.ts +++ b/packages/eslint-plugin/src/rules/interface-name-prefix.ts @@ -3,7 +3,7 @@ * @author Danny Fritz */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/member-delimiter-style.ts b/packages/eslint-plugin/src/rules/member-delimiter-style.ts index 51059a348f3b..ed980361d593 100644 --- a/packages/eslint-plugin/src/rules/member-delimiter-style.ts +++ b/packages/eslint-plugin/src/rules/member-delimiter-style.ts @@ -4,7 +4,7 @@ * @author Brad Zacher */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/member-naming.ts b/packages/eslint-plugin/src/rules/member-naming.ts index 20eec2576ed0..cb7866f40975 100644 --- a/packages/eslint-plugin/src/rules/member-naming.ts +++ b/packages/eslint-plugin/src/rules/member-naming.ts @@ -3,7 +3,7 @@ * @author Ian MacLeod */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/member-ordering.ts b/packages/eslint-plugin/src/rules/member-ordering.ts index 6ab793f57821..872e5c64d7b5 100644 --- a/packages/eslint-plugin/src/rules/member-ordering.ts +++ b/packages/eslint-plugin/src/rules/member-ordering.ts @@ -3,7 +3,7 @@ * @author Patricio Trevino */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts b/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts index c59d8b93c2d3..d457b709e590 100644 --- a/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts @@ -3,7 +3,7 @@ * @author Patricio Trevino */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/no-array-constructor.ts b/packages/eslint-plugin/src/rules/no-array-constructor.ts index 0fdfc5e5d84f..8c3bff08cf41 100644 --- a/packages/eslint-plugin/src/rules/no-array-constructor.ts +++ b/packages/eslint-plugin/src/rules/no-array-constructor.ts @@ -4,7 +4,7 @@ * @author Matt DuVall */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/no-empty-interface.ts b/packages/eslint-plugin/src/rules/no-empty-interface.ts index bfda506c63a2..65590af0b5e6 100644 --- a/packages/eslint-plugin/src/rules/no-empty-interface.ts +++ b/packages/eslint-plugin/src/rules/no-empty-interface.ts @@ -3,7 +3,7 @@ * @author Patricio Trevino */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/no-explicit-any.ts b/packages/eslint-plugin/src/rules/no-explicit-any.ts index 2e6e8a8149ae..01b810c44a26 100644 --- a/packages/eslint-plugin/src/rules/no-explicit-any.ts +++ b/packages/eslint-plugin/src/rules/no-explicit-any.ts @@ -4,7 +4,7 @@ * @author Patricio Trevino */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/no-extraneous-class.ts b/packages/eslint-plugin/src/rules/no-extraneous-class.ts index 9987b6dccbb5..850a688ca2dc 100644 --- a/packages/eslint-plugin/src/rules/no-extraneous-class.ts +++ b/packages/eslint-plugin/src/rules/no-extraneous-class.ts @@ -3,7 +3,7 @@ * @author Jed Fox */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/no-inferrable-types.ts b/packages/eslint-plugin/src/rules/no-inferrable-types.ts index dd37514f71f0..5d08c1093cc2 100644 --- a/packages/eslint-plugin/src/rules/no-inferrable-types.ts +++ b/packages/eslint-plugin/src/rules/no-inferrable-types.ts @@ -3,7 +3,7 @@ * @author James Garbutt */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/no-misused-new.ts b/packages/eslint-plugin/src/rules/no-misused-new.ts index 0b407ffc9943..319804f1a8b9 100644 --- a/packages/eslint-plugin/src/rules/no-misused-new.ts +++ b/packages/eslint-plugin/src/rules/no-misused-new.ts @@ -3,7 +3,7 @@ * @author Armano */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/no-namespace.ts b/packages/eslint-plugin/src/rules/no-namespace.ts index 81106aebbcf6..e2eaec925fc0 100644 --- a/packages/eslint-plugin/src/rules/no-namespace.ts +++ b/packages/eslint-plugin/src/rules/no-namespace.ts @@ -3,7 +3,7 @@ * @author Patricio Trevino */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/no-non-null-assertion.ts b/packages/eslint-plugin/src/rules/no-non-null-assertion.ts index 53e28d161bf0..9d795f570cb3 100644 --- a/packages/eslint-plugin/src/rules/no-non-null-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-non-null-assertion.ts @@ -3,7 +3,7 @@ * @author Macklin Underdown */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts b/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts index 6dccf8df300b..066fedae4c58 100644 --- a/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts @@ -3,7 +3,7 @@ * @author Armano */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/no-parameter-properties.ts b/packages/eslint-plugin/src/rules/no-parameter-properties.ts index aa74b0d5d9c3..e975e205c36e 100644 --- a/packages/eslint-plugin/src/rules/no-parameter-properties.ts +++ b/packages/eslint-plugin/src/rules/no-parameter-properties.ts @@ -3,7 +3,7 @@ * @author Patricio Trevino */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/no-this-alias.ts b/packages/eslint-plugin/src/rules/no-this-alias.ts index d1847c0be366..b9e08476fada 100644 --- a/packages/eslint-plugin/src/rules/no-this-alias.ts +++ b/packages/eslint-plugin/src/rules/no-this-alias.ts @@ -3,7 +3,7 @@ * @author Jed Fox */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts b/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts index 91dcb051058a..cd0b1f06fe5a 100644 --- a/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts +++ b/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts @@ -3,7 +3,7 @@ * @author Danny Fritz */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/no-type-alias.ts b/packages/eslint-plugin/src/rules/no-type-alias.ts index eecf33859c28..d54b06938593 100644 --- a/packages/eslint-plugin/src/rules/no-type-alias.ts +++ b/packages/eslint-plugin/src/rules/no-type-alias.ts @@ -3,7 +3,7 @@ * @author Patricio Trevino */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/no-unused-vars.ts b/packages/eslint-plugin/src/rules/no-unused-vars.ts index 8289dddbc123..c4daf7fb0cc7 100644 --- a/packages/eslint-plugin/src/rules/no-unused-vars.ts +++ b/packages/eslint-plugin/src/rules/no-unused-vars.ts @@ -3,7 +3,7 @@ * @author James Henry */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import baseRule from 'eslint/lib/rules/no-unused-vars'; import { Identifier } from 'estree'; import * as util from '../util'; diff --git a/packages/eslint-plugin/src/rules/no-var-requires.ts b/packages/eslint-plugin/src/rules/no-var-requires.ts index 37c85ef040c9..0a1be13c08e0 100644 --- a/packages/eslint-plugin/src/rules/no-var-requires.ts +++ b/packages/eslint-plugin/src/rules/no-var-requires.ts @@ -3,7 +3,7 @@ * @author Macklin Underdown */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/prefer-interface.ts b/packages/eslint-plugin/src/rules/prefer-interface.ts index f0c334919bbd..4972fddb4de9 100644 --- a/packages/eslint-plugin/src/rules/prefer-interface.ts +++ b/packages/eslint-plugin/src/rules/prefer-interface.ts @@ -3,7 +3,7 @@ * @author Armano */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts b/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts index 50d9ff961cad..d8a828ec0290 100644 --- a/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts +++ b/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts @@ -4,7 +4,7 @@ * @author Armano */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts index 2b5c3aa5c8c2..1280c592d717 100644 --- a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts +++ b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts @@ -4,7 +4,7 @@ * @author Armano */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import ts from 'typescript'; import * as util from '../util'; diff --git a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts index 6d3395f6f601..3511279b537e 100644 --- a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts +++ b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts @@ -4,7 +4,7 @@ * @author Patricio Trevino */ -import RuleModule from '../RuleModule'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/tests/rules/array-type.ts b/packages/eslint-plugin/tests/rules/array-type.ts index 64f4ad1aed4e..561d72bf3873 100644 --- a/packages/eslint-plugin/tests/rules/array-type.ts +++ b/packages/eslint-plugin/tests/rules/array-type.ts @@ -784,7 +784,7 @@ describe('array-type (nested)', () => { function testOutput(option: string, code: string, output: string): void { const linter = new Linter(); - linter.defineRule('array-type', Object.assign({}, rule)); + linter.defineRule('array-type', Object.assign({}, rule) as any); const result = linter.verifyAndFix( code, { @@ -809,23 +809,23 @@ describe('array-type (nested)', () => { testOutput( 'array', ` - class Foo>> extends Bar> implements Baz> { - private s: Array +class Foo>> extends Bar> implements Baz> { + private s: Array - constructor (p: Array) { - return new Array() - } - } - `, + constructor (p: Array) { + return new Array() + } +} + `, ` - class Foo extends Bar implements Baz { - private s: T[] +class Foo extends Bar implements Baz { + private s: T[] - constructor (p: T[]) { - return new Array() - } - } - ` + constructor (p: T[]) { + return new Array() + } +} + ` ); testOutput( 'array-simple', diff --git a/packages/eslint-plugin/typings/eslint-rules.d.ts b/packages/eslint-plugin/typings/eslint-rules.d.ts index 9c7c0dbeb4b6..27a5c408da3f 100644 --- a/packages/eslint-plugin/typings/eslint-rules.d.ts +++ b/packages/eslint-plugin/typings/eslint-rules.d.ts @@ -1,12 +1,8 @@ declare module 'eslint/lib/rules/*' { - import { Node } from 'estree'; - import { Rule } from 'eslint'; + import RuleModule from 'ts-eslint'; // intentionally redefined here instead of using Rule.RuleListener // because eslint only uses the `node => void` signature - const rule: { - create(context: Rule.RuleContext): Record void>; - meta: Rule.RuleMetaData; - }; + const rule: RuleModule; export = rule; } diff --git a/packages/eslint-plugin/typings/eslint.d.ts b/packages/eslint-plugin/typings/eslint.d.ts index 1205bc5f0140..a7d2cf8f641f 100644 --- a/packages/eslint-plugin/typings/eslint.d.ts +++ b/packages/eslint-plugin/typings/eslint.d.ts @@ -19,8 +19,7 @@ declare module 'eslint' { interface RuleTester { run( name: string, - // have to keep the base eslint def for our base eslint-rule test cases - rule: RuleModule | Rule.RuleModule, + rule: RuleModule, tests: RuleTesterRunTests ): void; } diff --git a/packages/eslint-plugin/typings/ts-eslint.d.ts b/packages/eslint-plugin/typings/ts-eslint.d.ts new file mode 100644 index 000000000000..a82f534c5353 --- /dev/null +++ b/packages/eslint-plugin/typings/ts-eslint.d.ts @@ -0,0 +1,408 @@ +/* +Redefine these types for these reasons: +1) We can better control what properties are option and what are not. +2) We have to replace definitions with our definitions which use our typescript-estree types. +3) We can better document the fields so it's easier for new contributers to understand. + +The def is wrapped up in a fake module so that it can be used in eslint-rules.d.ts +*/ + +declare module 'ts-eslint' { + import { TSESTree } from '@typescript-eslint/typescript-estree'; + import { ParserServices } from '@typescript-eslint/parser'; + import { AST, Linter, Scope } from 'eslint'; + import { Comment as ESTreeComment } from 'estree'; + import { JSONSchema4 } from 'json-schema'; + + //#region SourceCode + + // eslint-disable-next-line @typescript-eslint/no-namespace + namespace SourceCode { + export interface Config { + text: string; + ast: AST.Program; + parserServices?: ParserServices; + scopeManager?: Scope.ScopeManager; + visitorKeys?: VisitorKeys; + } + + export interface VisitorKeys { + [nodeType: string]: string[]; + } + + export type FilterPredicate = ( + tokenOrComment: AST.Token | ESTreeComment + ) => boolean; + + export type CursorWithSkipOptions = + | number + | FilterPredicate + | { + includeComments?: boolean; + filter?: FilterPredicate; + skip?: number; + }; + + export type CursorWithCountOptions = + | number + | FilterPredicate + | { + includeComments?: boolean; + filter?: FilterPredicate; + count?: number; + }; + } + + // eslint-disable-next-line no-redeclare + class SourceCode { + text: string; + ast: AST.Program; + lines: string[]; + hasBOM: boolean; + parserServices: ParserServices; + scopeManager: Scope.ScopeManager; + visitorKeys: SourceCode.VisitorKeys; + + constructor(text: string, ast: AST.Program); + // eslint-disable-next-line no-dupe-class-members + constructor(config: SourceCode.Config); + + static splitLines(text: string): string[]; + + getText( + node?: TSESTree.Node, + beforeCount?: number, + afterCount?: number + ): string; + + getLines(): string[]; + + getAllComments(): ESTreeComment[]; + + getComments( + node: TSESTree.Node + ): { leading: ESTreeComment[]; trailing: ESTreeComment[] }; + + getJSDocComment(node: TSESTree.Node): AST.Token | null; + + getNodeByRangeIndex(index: number): TSESTree.Node | null; + + isSpaceBetweenTokens(first: AST.Token, second: AST.Token): boolean; + + getLocFromIndex(index: number): TSESTree.LineAndColumnData; + + getIndexFromLoc(location: TSESTree.LineAndColumnData): number; + + // Inherited methods from TokenStore + // --------------------------------- + + getTokenByRangeStart( + offset: number, + options?: { includeComments?: boolean } + ): AST.Token | null; + + getFirstToken( + node: TSESTree.Node, + options?: SourceCode.CursorWithSkipOptions + ): AST.Token | null; + + getFirstTokens( + node: TSESTree.Node, + options?: SourceCode.CursorWithCountOptions + ): AST.Token[]; + + getLastToken( + node: TSESTree.Node, + options?: SourceCode.CursorWithSkipOptions + ): AST.Token | null; + + getLastTokens( + node: TSESTree.Node, + options?: SourceCode.CursorWithCountOptions + ): AST.Token[]; + + getTokenBefore( + node: TSESTree.Node | AST.Token | ESTreeComment, + options?: SourceCode.CursorWithSkipOptions + ): AST.Token | null; + + getTokensBefore( + node: TSESTree.Node | AST.Token | ESTreeComment, + options?: SourceCode.CursorWithCountOptions + ): AST.Token[]; + + getTokenAfter( + node: TSESTree.Node | AST.Token | ESTreeComment, + options?: SourceCode.CursorWithSkipOptions + ): AST.Token | null; + + getTokensAfter( + node: TSESTree.Node | AST.Token | ESTreeComment, + options?: SourceCode.CursorWithCountOptions + ): AST.Token[]; + + getFirstTokenBetween( + left: TSESTree.Node | AST.Token | ESTreeComment, + right: TSESTree.Node | AST.Token | ESTreeComment, + options?: SourceCode.CursorWithSkipOptions + ): AST.Token | null; + + getFirstTokensBetween( + left: TSESTree.Node | AST.Token | ESTreeComment, + right: TSESTree.Node | AST.Token | ESTreeComment, + options?: SourceCode.CursorWithCountOptions + ): AST.Token[]; + + getLastTokenBetween( + left: TSESTree.Node | AST.Token | ESTreeComment, + right: TSESTree.Node | AST.Token | ESTreeComment, + options?: SourceCode.CursorWithSkipOptions + ): AST.Token | null; + + getLastTokensBetween( + left: TSESTree.Node | AST.Token | ESTreeComment, + right: TSESTree.Node | AST.Token | ESTreeComment, + options?: SourceCode.CursorWithCountOptions + ): AST.Token[]; + + getTokensBetween( + left: TSESTree.Node | AST.Token | ESTreeComment, + right: TSESTree.Node | AST.Token | ESTreeComment, + padding?: + | number + | SourceCode.FilterPredicate + | SourceCode.CursorWithCountOptions + ): AST.Token[]; + + getTokens( + node: TSESTree.Node, + beforeCount?: number, + afterCount?: number + ): AST.Token[]; + // eslint-disable-next-line no-dupe-class-members + getTokens( + node: TSESTree.Node, + options: SourceCode.FilterPredicate | SourceCode.CursorWithCountOptions + ): AST.Token[]; + + commentsExistBetween( + left: TSESTree.Node | AST.Token, + right: TSESTree.Node | AST.Token + ): boolean; + + getCommentsBefore(nodeOrToken: TSESTree.Node | AST.Token): ESTreeComment[]; + + getCommentsAfter(nodeOrToken: TSESTree.Node | AST.Token): ESTreeComment[]; + + getCommentsInside(node: TSESTree.Node): ESTreeComment[]; + } + + //#endregion SourceCode + + //#region Rule + + interface RuleMetaData { + /** + * True if the rule is deprecated, false otherwise + */ + deprecated?: boolean; + /** + * Documentation for the rule + */ + docs: { + /** + * The general category the rule falls within + */ + category: 'Best Practices' | 'Stylistic Issues' | 'Variables'; + /** + * Concise description of the rule + */ + description: string; + /** + * Extra information linking the rule to a tslint rule + */ + extraDescription?: string[]; + /** + * The recommendation level for the rule. + * Used by the build tools to generate the recommended config. + * Set to false to not include it as a recommendation + */ + recommended: 'error' | 'warn' | false; + /** + * The URL of the rule's docs + */ + url: string; + }; + /** + * The fixer category. Omit if there is no fixer + */ + fixable?: 'code' | 'whitespace'; + /** + * A map of messages which the rule can report. + * The key is the messageId, and the string is the parameterised error string. + * See: https://eslint.org/docs/developer-guide/working-with-rules#messageids + */ + messages: { + [messageId: string]: string; + }; + /** + * The type of rule. + * - `"problem"` means the rule is identifying code that either will cause an error or may cause a confusing behavior. Developers should consider this a high priority to resolve. + * - `"suggestion"` means the rule is identifying something that could be done in a better way but no errors will occur if the code isn’t changed. + * - `"layout"` means the rule cares primarily about whitespace, semicolons, commas, and parentheses, all the parts of the program that determine how the code looks rather than how it executes. These rules work on parts of the code that aren’t specified in the AST. + */ + type: 'suggestion' | 'problem' | 'layout'; + /** + * The name of the rule this rule was replaced by, if it was deprecated. + */ + replacedBy?: string; + /** + * The options schema. Supply an empty array if there are no options. + */ + schema: JSONSchema4 | JSONSchema4[]; + } + + interface RuleListener { + // This isn't the correct signature, but it makes it easier to do custom unions within reusable listneers + // never will break someone's code unless they specifically type the function argument + [key: string]: (node: never) => void; + } + + interface RuleFix { + range: AST.Range; + text: string; + } + + interface RuleFixer { + insertTextAfter( + nodeOrToken: TSESTree.Node | AST.Token, + text: string + ): RuleFix; + + insertTextAfterRange(range: AST.Range, text: string): RuleFix; + + insertTextBefore( + nodeOrToken: TSESTree.Node | AST.Token, + text: string + ): RuleFix; + + insertTextBeforeRange(range: AST.Range, text: string): RuleFix; + + remove(nodeOrToken: TSESTree.Node | AST.Token): RuleFix; + + removeRange(range: AST.Range): RuleFix; + + replaceText(nodeOrToken: TSESTree.Node | AST.Token, text: string): RuleFix; + + replaceTextRange(range: AST.Range, text: string): RuleFix; + } + + type ReportFixFunction = (fixer: RuleFixer) => null | RuleFix | RuleFix[]; + + interface ReportDescriptor { + /** + * The parameters for the message string associated with `messageId`. + */ + data?: { [key: string]: string }; + /** + * The fixer function. + */ + fix?: ReportFixFunction | null; + /** + * The messageId which is being reported. + */ + messageId: string; + /** + * The Node which the report is being attached to + */ + node: TSESTree.Node; + } + + interface RuleContext { + /** + * The rule ID. + */ + id: string; + /** + * An array of the configured options for this rule. + * This array does not include the rule severity. + */ + options: TOpts; + /** + * The shared settings from configuration. + * We do not have any shared settings in this plugin. + */ + settings: {}; + /** + * The name of the parser from configuration. + */ + parserPath: string; + /** + * The parser options configured for this run + */ + parserOptions: Linter.ParserOptions; + /** + * An object containing parser-provided services for rules + */ + parserServices?: ParserServices; + + /** + * Returns an array of the ancestors of the currently-traversed node, starting at + * the root of the AST and continuing through the direct parent of the current node. + * This array does not include the currently-traversed node itself. + */ + getAncestors(): TSESTree.Node[]; + + /** + * Returns a list of variables declared by the given node. + * This information can be used to track references to variables. + */ + getDeclaredVariables(node: TSESTree.Node): Scope.Variable[]; + + /** + * Returns the filename associated with the source. + */ + getFilename(): string; + + /** + * Returns the scope of the currently-traversed node. + * This information can be used track references to variables. + */ + getScope(): Scope.Scope; + + /** + * Returns a SourceCode object that you can use to work with the source that + * was passed to ESLint. + */ + getSourceCode(): SourceCode; + + /** + * Marks a variable with the given name in the current scope as used. + * This affects the no-unused-vars rule. + */ + markVariableAsUsed(name: string): boolean; + + /** + * Reports a problem in the code. + */ + report(descriptor: ReportDescriptor): void; + } + + interface RuleModule { + /** + * Metadata about the rule + */ + meta: RuleMetaData; + + /** + * Function which returns an object with methods that ESLint calls to “visit” + * nodes while traversing the abstract syntax tree. + */ + create(context: RuleContext): RuleListener; + } + + //#endregion Rule + + export { RuleContext, ReportFixFunction }; + export default RuleModule; +} From 8f2e7e5b4c4230dbc9e03fc987dba6aa825bd5f8 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Thu, 31 Jan 2019 09:11:19 -0800 Subject: [PATCH 26/92] add back tests accidentally deleted from adjacent-overload-sigs --- .../rules/adjacent-overload-signatures.ts | 213 +++++++++++++++++- 1 file changed, 212 insertions(+), 1 deletion(-) diff --git a/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.ts b/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.ts index 79ad64cb5ae4..d583a5554628 100644 --- a/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.ts +++ b/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.ts @@ -19,12 +19,223 @@ const ruleTester = new RuleTester({ }); ruleTester.run('adjacent-overload-signatures', rule, { - valid: [], + valid: [ + { + code: ` +function error(a: string); +function error(b: number); +function error(ab: string|number){ } +export { error }; + `, + parserOptions: { sourceType: 'module' } + }, + { + code: ` +import { connect } from 'react-redux'; +export interface ErrorMessageModel { message: string; } +function mapStateToProps() { } +function mapDispatchToProps() { } +export default connect(mapStateToProps, mapDispatchToProps)(ErrorMessage); + `, + parserOptions: { sourceType: 'module' } + }, + ` +export const foo = "a", bar = "b"; +export interface Foo {} +export class Foo {} + `, + ` +export interface Foo {} +export const foo = "a", bar = "b"; +export class Foo {} + `, + ` +const foo = "a", bar = "b"; +interface Foo {} +class Foo {} + `, + ` +interface Foo {} +const foo = "a", bar = "b"; +class Foo {} + `, + ` +export class Foo {} +export class Bar {} + export type FooBar = Foo | Bar; + `, + ` +export interface Foo {} +export class Foo {} +export class Bar {} + export type FooBar = Foo | Bar; + `, + ` +export function foo(s: string); +export function foo(n: number); +export function foo(sn: string | number) {} +export function bar(): void {} +export function baz(): void {} + `, + ` +function foo(s: string); +function foo(n: number); +function foo(sn: string | number) {} +function bar(): void {} +function baz(): void {} + `, + ` +declare function foo(s: string); +declare function foo(n: number); +declare function foo(sn: string | number); +declare function bar(): void; +declare function baz(): void; + `, + ` +declare module "Foo" { + export function foo(s: string): void; + export function foo(n: number): void; + export function foo(sn: string | number): void; + export function bar(): void; + export function baz(): void; +} + `, + ` +declare namespace Foo { + export function foo(s: string): void; + export function foo(n: number): void; + export function foo(sn: string | number): void; + export function bar(): void; + export function baz(): void; +} + `, + ` +type Foo = { + foo(s: string): void; + foo(n: number): void; + foo(sn: string | number): void; + bar(): void; + baz(): void; +} + `, + ` +type Foo = { + foo(s: string): void; + ["foo"](n: number): void; + foo(sn: string | number): void; + bar(): void; + baz(): void; +} + `, + ` +interface Foo { + (s: string): void; + (n: number): void; + (sn: string | number): void; + foo(n: number): void; + bar(): void; + baz(): void; +} + `, + ` +interface Foo { + foo(s: string): void; + foo(n: number): void; + foo(sn: string | number): void; + bar(): void; + baz(): void; +} + `, + ` +interface Foo { + foo(s: string): void; + ["foo"](n: number): void; + foo(sn: string | number): void; + bar(): void; + baz(): void; +} + `, + ` +interface Foo { + foo(): void; + bar: { + baz(s: string): void; + baz(n: number): void; + baz(sn: string | number): void; + } +} + `, + ` +interface Foo { + new(s: string); + new(n: number); + new(sn: string | number); + foo(): void; +} + `, + ` +class Foo { + constructor(s: string); + constructor(n: number); + constructor(sn: string | number) {} + bar(): void {} + baz(): void {} +} + `, + ` +class Foo { + foo(s: string): void; + foo(n: number): void; + foo(sn: string | number): void {} + bar(): void {} + baz(): void {} +} + `, + ` +class Foo { + foo(s: string): void; + ["foo"](n: number): void; + foo(sn: string | number): void {} + bar(): void {} + baz(): void {} +} + `, + ` +class Foo { + name: string; + foo(s: string): void; + foo(n: number): void; + foo(sn: string | number): void {} + bar(): void {} + baz(): void {} +} + `, + // examples from https://github.com/nzakas/eslint-plugin-typescript/issues/138 + 'export default function(foo : T) {}', + 'export default function named(foo : T) {}' + ], invalid: [ { code: ` export function foo(s: string); export function foo(n: number); +export function bar(): void {} +export function baz(): void {} +export function foo(sn: string | number) {} + `, + errors: [ + { + messageId: 'adjacentSignature', + data: { name: 'foo' }, + line: 6, + column: 1 + } + ] + }, + { + code: ` +export function foo(s: string); +export function foo(n: number); export type bar = number; export type baz = number | string; export function foo(sn: string | number) {} From b08b70a7d000dbc6d422e93abdb2db97303b89e6 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Thu, 31 Jan 2019 09:18:00 -0800 Subject: [PATCH 27/92] camelcase --- packages/eslint-plugin/src/rules/camelcase.ts | 43 ++++++++++++------- .../eslint-plugin/typings/eslint-rules.d.ts | 24 +++++++++-- packages/eslint-plugin/typings/ts-eslint.d.ts | 39 +++++++++-------- 3 files changed, 69 insertions(+), 37 deletions(-) diff --git a/packages/eslint-plugin/src/rules/camelcase.ts b/packages/eslint-plugin/src/rules/camelcase.ts index 6b5dfce864f3..036267074fc1 100644 --- a/packages/eslint-plugin/src/rules/camelcase.ts +++ b/packages/eslint-plugin/src/rules/camelcase.ts @@ -3,14 +3,21 @@ * @author Patricio Trevino */ -import RuleModule from '../RuleModule'; +import { TSESTree } from '@typescript-eslint/typescript-estree'; +import RuleModule from 'ts-eslint'; import baseRule from 'eslint/lib/rules/camelcase'; import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -const defaultOptions = [ +interface Options { + ignoreDestructuring: boolean; + properties: 'always' | 'never'; + allow: string[]; +} + +const defaultOptions: [Options] = [ { allow: ['^UNSAFE_'], ignoreDestructuring: false, @@ -18,15 +25,18 @@ const defaultOptions = [ } ]; -/* eslint-disable eslint-plugin/require-meta-type */ -const rule: RuleModule = { - meta: Object.assign({}, baseRule.meta, { +const rule: RuleModule<[Options], 'notCamelCase'> = { + meta: { + type: 'suggestion', docs: { description: 'Enforce camelCase naming convention', + category: 'Stylistic Issues', url: util.metaDocsUrl('ban-types'), recommended: 'error' - } - }), + }, + schema: baseRule.meta.schema!, + messages: baseRule.meta.messages as Record<'notCamelCase', string> + }, create(context) { const rules = baseRule.create(context); @@ -66,17 +76,21 @@ const rule: RuleModule = { /** * Checks if the the node is a valid TypeScript property type. - * @param {Node} node the node to be validated. + * @param node the node to be validated. * @returns true if the node is a TypeScript property type. * @private */ - function isTSPropertyType(node): boolean { - if (!node.parent) return false; - if (TS_PROPERTY_TYPES.includes(node.parent.type)) return true; + function isTSPropertyType(node: TSESTree.Node): boolean { + if (!node.parent) { + return false; + } + if (TS_PROPERTY_TYPES.includes(node.parent.type)) { + return true; + } if (node.parent.type === 'AssignmentPattern') { return ( - node.parent.parent && + node.parent.parent !== undefined && TS_PROPERTY_TYPES.includes(node.parent.parent.type) ); } @@ -85,7 +99,7 @@ const rule: RuleModule = { } return { - Identifier(node) { + Identifier(node: TSESTree.Identifier) { /* * Leading and trailing underscores are commonly used to flag * private/protected identifiers, strip them @@ -111,8 +125,7 @@ const rule: RuleModule = { } // Let the base rule deal with the rest - // eslint-disable-next-line new-cap - rules.Identifier!(node); + rules.Identifier(node); } }; } diff --git a/packages/eslint-plugin/typings/eslint-rules.d.ts b/packages/eslint-plugin/typings/eslint-rules.d.ts index 27a5c408da3f..d195c104ca79 100644 --- a/packages/eslint-plugin/typings/eslint-rules.d.ts +++ b/packages/eslint-plugin/typings/eslint-rules.d.ts @@ -1,8 +1,26 @@ declare module 'eslint/lib/rules/*' { import RuleModule from 'ts-eslint'; - // intentionally redefined here instead of using Rule.RuleListener - // because eslint only uses the `node => void` signature - const rule: RuleModule; + const rule: RuleModule; + export = rule; +} + +declare module 'eslint/lib/rules/camelcase' { + import { TSESTree } from '@typescript-eslint/typescript-estree'; + import RuleModule from 'ts-eslint'; + + const rule: RuleModule< + [ + { + ignoreDestructuring: boolean; + properties: 'always' | 'never'; + allow: string[]; + } + ], + 'notCamelCase', + { + Identifier: (node: TSESTree.Node) => void; + } + >; export = rule; } diff --git a/packages/eslint-plugin/typings/ts-eslint.d.ts b/packages/eslint-plugin/typings/ts-eslint.d.ts index a82f534c5353..8f16c3b488bf 100644 --- a/packages/eslint-plugin/typings/ts-eslint.d.ts +++ b/packages/eslint-plugin/typings/ts-eslint.d.ts @@ -201,7 +201,7 @@ declare module 'ts-eslint' { //#region Rule - interface RuleMetaData { + interface RuleMetaData { /** * True if the rule is deprecated, false otherwise */ @@ -242,9 +242,7 @@ declare module 'ts-eslint' { * The key is the messageId, and the string is the parameterised error string. * See: https://eslint.org/docs/developer-guide/working-with-rules#messageids */ - messages: { - [messageId: string]: string; - }; + messages: Record; /** * The type of rule. * - `"problem"` means the rule is identifying code that either will cause an error or may cause a confusing behavior. Developers should consider this a high priority to resolve. @@ -262,12 +260,6 @@ declare module 'ts-eslint' { schema: JSONSchema4 | JSONSchema4[]; } - interface RuleListener { - // This isn't the correct signature, but it makes it easier to do custom unions within reusable listneers - // never will break someone's code unless they specifically type the function argument - [key: string]: (node: never) => void; - } - interface RuleFix { range: AST.Range; text: string; @@ -299,11 +291,11 @@ declare module 'ts-eslint' { type ReportFixFunction = (fixer: RuleFixer) => null | RuleFix | RuleFix[]; - interface ReportDescriptor { + interface ReportDescriptor { /** * The parameters for the message string associated with `messageId`. */ - data?: { [key: string]: string }; + data?: Record; /** * The fixer function. */ @@ -311,14 +303,14 @@ declare module 'ts-eslint' { /** * The messageId which is being reported. */ - messageId: string; + messageId: TMessageIds; /** * The Node which the report is being attached to */ node: TSESTree.Node; } - interface RuleContext { + interface RuleContext { /** * The rule ID. */ @@ -327,7 +319,7 @@ declare module 'ts-eslint' { * An array of the configured options for this rule. * This array does not include the rule severity. */ - options: TOpts; + options: TOptions; /** * The shared settings from configuration. * We do not have any shared settings in this plugin. @@ -385,20 +377,29 @@ declare module 'ts-eslint' { /** * Reports a problem in the code. */ - report(descriptor: ReportDescriptor): void; + report(descriptor: ReportDescriptor): void; } - interface RuleModule { + // This isn't the correct signature, but it makes it easier to do custom unions within reusable listneers + // never will break someone's code unless they specifically type the function argument + type RuleListener = Record void>; + + interface RuleModule< + TOptions extends any[] = never[], + TMessageIds extends string = never, + // for extending base rules + TRuleListener extends RuleListener = RuleListener + > { /** * Metadata about the rule */ - meta: RuleMetaData; + meta: RuleMetaData; /** * Function which returns an object with methods that ESLint calls to “visit” * nodes while traversing the abstract syntax tree. */ - create(context: RuleContext): RuleListener; + create(context: RuleContext): TRuleListener; } //#endregion Rule From 6f33e82ef5923b0d84d7ca869b7d734d0fab9b36 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Thu, 31 Jan 2019 10:43:20 -0800 Subject: [PATCH 28/92] tweak generics to be stricter and more ergonomic --- .vscode/settings.json | 2 +- .../src/rules/adjacent-overload-signatures.ts | 2 +- .../eslint-plugin/src/rules/array-type.ts | 12 +++++- packages/eslint-plugin/src/rules/ban-types.ts | 28 ++++++------ packages/eslint-plugin/src/rules/camelcase.ts | 18 ++++---- .../eslint-plugin/tests/rules/ban-types.ts | 3 +- .../eslint-plugin/typings/eslint-rules.d.ts | 14 +++--- packages/eslint-plugin/typings/eslint.d.ts | 43 ++++++++++++++++--- packages/eslint-plugin/typings/ts-eslint.d.ts | 10 ++--- packages/typescript-estree/src/typedefs.ts | 2 +- yarn.lock | 6 +-- 11 files changed, 91 insertions(+), 49 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index adcf2422e8f3..2c4de8650a59 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -18,7 +18,7 @@ "files.trimTrailingWhitespace": true, // typescript auto-format settings - "typescript.tsdk": "node_modules/typescript/lib", +"typescript.tsdk": "node_modules/typescript/lib", "javascript.preferences.importModuleSpecifier": "auto", "typescript.preferences.importModuleSpecifier": "auto", "javascript.preferences.quoteStyle": "single", diff --git a/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts b/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts index 0e87fcaebb0a..6aeaff6184a9 100644 --- a/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts +++ b/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts @@ -19,7 +19,7 @@ type RuleNode = | TSESTree.TSInterfaceBody; type Member = TSESTree.ClassElement | TSESTree.Statement | TSESTree.TypeElement; -const rule: RuleModule = { +const rule: RuleModule<'adjacentSignature', []> = { meta: { type: 'suggestion', docs: { diff --git a/packages/eslint-plugin/src/rules/array-type.ts b/packages/eslint-plugin/src/rules/array-type.ts index e3ddc8e765f1..62df78f5cd44 100644 --- a/packages/eslint-plugin/src/rules/array-type.ts +++ b/packages/eslint-plugin/src/rules/array-type.ts @@ -76,9 +76,17 @@ function typeNeedsParentheses(node: TSESTree.Node): boolean { // Rule Definition //------------------------------------------------------------------------------ -const defaultOptions = ['array']; +type Options = ['array' | 'generic' | 'array-simple']; -const rule: RuleModule = { +const defaultOptions: Options = ['array']; + +const rule: RuleModule< + | 'errorStringGeneric' + | 'errorStringGenericSimple' + | 'errorStringArray' + | 'errorStringArraySimple', + Options +> = { meta: { type: 'suggestion', docs: { diff --git a/packages/eslint-plugin/src/rules/ban-types.ts b/packages/eslint-plugin/src/rules/ban-types.ts index f7696b19d81c..a66deb8da649 100644 --- a/packages/eslint-plugin/src/rules/ban-types.ts +++ b/packages/eslint-plugin/src/rules/ban-types.ts @@ -11,19 +11,21 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -interface Options { - types: Record< - string, - | string - | null - | { - message: string; - fixWith?: string; - } - >; -} +type Options = [ + { + types: Record< + string, + | string + | null + | { + message: string; + fixWith?: string; + } + >; + } +]; -const defaultOptions: [Options] = [ +const defaultOptions: Options = [ { types: { String: { @@ -50,7 +52,7 @@ const defaultOptions: [Options] = [ } ]; -const rule: RuleModule<[Options]> = { +const rule: RuleModule<'bannedTypeMessage', Options> = { meta: { type: 'suggestion', docs: { diff --git a/packages/eslint-plugin/src/rules/camelcase.ts b/packages/eslint-plugin/src/rules/camelcase.ts index 036267074fc1..bfb045df2753 100644 --- a/packages/eslint-plugin/src/rules/camelcase.ts +++ b/packages/eslint-plugin/src/rules/camelcase.ts @@ -11,13 +11,15 @@ import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -interface Options { - ignoreDestructuring: boolean; - properties: 'always' | 'never'; - allow: string[]; -} +type Options = [ + { + ignoreDestructuring: boolean; + properties: 'always' | 'never'; + allow: string[]; + } +]; -const defaultOptions: [Options] = [ +const defaultOptions: Options = [ { allow: ['^UNSAFE_'], ignoreDestructuring: false, @@ -25,7 +27,7 @@ const defaultOptions: [Options] = [ } ]; -const rule: RuleModule<[Options], 'notCamelCase'> = { +const rule: RuleModule<'notCamelCase', Options> = { meta: { type: 'suggestion', docs: { @@ -35,7 +37,7 @@ const rule: RuleModule<[Options], 'notCamelCase'> = { recommended: 'error' }, schema: baseRule.meta.schema!, - messages: baseRule.meta.messages as Record<'notCamelCase', string> + messages: baseRule.meta.messages }, create(context) { diff --git a/packages/eslint-plugin/tests/rules/ban-types.ts b/packages/eslint-plugin/tests/rules/ban-types.ts index c5726d4e597c..3bdb2706d40e 100644 --- a/packages/eslint-plugin/tests/rules/ban-types.ts +++ b/packages/eslint-plugin/tests/rules/ban-types.ts @@ -18,7 +18,8 @@ const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); -const options = [ +// TODO - figure out a better way to type this that doesn't break the generics +const options: any = [ { types: { String: { diff --git a/packages/eslint-plugin/typings/eslint-rules.d.ts b/packages/eslint-plugin/typings/eslint-rules.d.ts index d195c104ca79..cbd44063c53f 100644 --- a/packages/eslint-plugin/typings/eslint-rules.d.ts +++ b/packages/eslint-plugin/typings/eslint-rules.d.ts @@ -1,15 +1,16 @@ -declare module 'eslint/lib/rules/*' { - import RuleModule from 'ts-eslint'; - - const rule: RuleModule; - export = rule; -} +// don't provide a general import case so that people have to strictly type out a declaration +// declare module 'eslint/lib/rules/*' { +// import RuleModule from 'ts-eslint'; +// const rule: RuleModule; +// export = rule; +// } declare module 'eslint/lib/rules/camelcase' { import { TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; const rule: RuleModule< + 'notCamelCase', [ { ignoreDestructuring: boolean; @@ -17,7 +18,6 @@ declare module 'eslint/lib/rules/camelcase' { allow: string[]; } ], - 'notCamelCase', { Identifier: (node: TSESTree.Node) => void; } diff --git a/packages/eslint-plugin/typings/eslint.d.ts b/packages/eslint-plugin/typings/eslint.d.ts index a7d2cf8f641f..56b5ff3d92f5 100644 --- a/packages/eslint-plugin/typings/eslint.d.ts +++ b/packages/eslint-plugin/typings/eslint.d.ts @@ -3,7 +3,7 @@ // module augmentation is weird import { RuleTester, Scope } from 'eslint'; import { TSESTree } from '@typescript-eslint/typescript-estree'; -import RuleModule from '../src/RuleModule'; +import RuleModule from 'ts-eslint'; declare module 'eslint' { namespace Scope { interface Variable { @@ -11,16 +11,45 @@ declare module 'eslint' { } } - export interface RuleTesterRunTests { + interface ValidTestCase { + code: string; + options?: TOptions; + filename?: string; + parserOptions?: Linter.ParserOptions; + settings?: Record; + parser?: string; + globals?: Record; + } + + interface InvalidTestCase + extends ValidTestCase { + errors: TestCaseError[]; + output?: string | null; + } + + interface TestCaseError { + messageId: TMessageIds; + data?: Record; + // type?: string; + line?: number; + column?: number; + // endLine?: number; + // endColumn?: number; + } + + interface RuleTesterRunTests< + TMessageIds extends string, + TOptions extends any[] + > { // RuleTester.run also accepts strings for valid cases - valid: (RuleTester.ValidTestCase | string)[]; - invalid: RuleTester.InvalidTestCase[]; + valid: (ValidTestCase | string)[]; + invalid: InvalidTestCase[]; } interface RuleTester { - run( + run( name: string, - rule: RuleModule, - tests: RuleTesterRunTests + rule: RuleModule, + tests: RuleTesterRunTests ): void; } } diff --git a/packages/eslint-plugin/typings/ts-eslint.d.ts b/packages/eslint-plugin/typings/ts-eslint.d.ts index 8f16c3b488bf..065342941ae2 100644 --- a/packages/eslint-plugin/typings/ts-eslint.d.ts +++ b/packages/eslint-plugin/typings/ts-eslint.d.ts @@ -295,7 +295,7 @@ declare module 'ts-eslint' { /** * The parameters for the message string associated with `messageId`. */ - data?: Record; + data?: Record; /** * The fixer function. */ @@ -310,7 +310,7 @@ declare module 'ts-eslint' { node: TSESTree.Node; } - interface RuleContext { + interface RuleContext { /** * The rule ID. */ @@ -385,8 +385,8 @@ declare module 'ts-eslint' { type RuleListener = Record void>; interface RuleModule< - TOptions extends any[] = never[], - TMessageIds extends string = never, + TMessageIds extends string, + TOptions extends any[], // for extending base rules TRuleListener extends RuleListener = RuleListener > { @@ -399,7 +399,7 @@ declare module 'ts-eslint' { * Function which returns an object with methods that ESLint calls to “visit” * nodes while traversing the abstract syntax tree. */ - create(context: RuleContext): TRuleListener; + create(context: RuleContext): TRuleListener; } //#endregion Rule diff --git a/packages/typescript-estree/src/typedefs.ts b/packages/typescript-estree/src/typedefs.ts index b5b00b7a85a8..ef8ba3966da7 100644 --- a/packages/typescript-estree/src/typedefs.ts +++ b/packages/typescript-estree/src/typedefs.ts @@ -1271,7 +1271,7 @@ export interface TSTypeAssertion extends NodeBase { export interface TSTypeLiteral extends NodeBase { type: 'TSTypeLiteral'; - members: TypeElement; + members: TypeElement[]; } export interface TSTypeOperator extends NodeBase { diff --git a/yarn.lock b/yarn.lock index 7da2adad508f..180a9f89f8bf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6931,9 +6931,9 @@ typedarray@^0.0.6: integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= typescript@~3.2.1: - version "3.2.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.2.tgz#fe8101c46aa123f8353523ebdcf5730c2ae493e5" - integrity sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg== + version "3.2.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.4.tgz#c585cb952912263d915b462726ce244ba510ef3d" + integrity sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg== uglify-js@^3.1.4: version "3.4.9" From 99f14a129131f846e024e736a4d480746efe488c Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Thu, 31 Jan 2019 17:24:50 -0800 Subject: [PATCH 29/92] rename test files and retype RuleTester --- .vscode/launch.json | 2 +- packages/eslint-plugin/jest.config.js | 2 +- packages/eslint-plugin/src/rules/camelcase.ts | 16 +++--- packages/eslint-plugin/src/util.ts | 10 ++-- packages/eslint-plugin/tests/RuleTester.ts | 50 +++++++++++++++++++ .../{no-dupe-args.ts => no-dupe-args.test.ts} | 2 +- ...globals.ts => no-implicit-globals.test.ts} | 2 +- .../{no-redeclare.ts => no-redeclare.test.ts} | 2 +- ...obals.ts => no-restricted-globals.test.ts} | 2 +- .../{no-shadow.ts => no-shadow.test.ts} | 2 +- .../{no-undef.ts => no-undef.test.ts} | 2 +- ...-unused-vars.ts => no-unused-vars.test.ts} | 2 +- ...define.ts => no-use-before-define.test.ts} | 2 +- .../{strict.ts => strict.test.ts} | 2 +- ...s => adjacent-overload-signatures.test.ts} | 2 +- .../{array-type.ts => array-type.test.ts} | 3 +- .../rules/{ban-types.ts => ban-types.test.ts} | 2 +- .../rules/{camelcase.ts => camelcase.test.ts} | 42 ++++++++++++---- ...me-casing.ts => class-name-casing.test.ts} | 2 +- ... => explicit-function-return-type.test.ts} | 2 +- ... => explicit-member-accessibility.test.ts} | 2 +- ...-naming.ts => generic-type-naming.test.ts} | 2 +- .../tests/rules/{indent.ts => indent.test.ts} | 0 ...refix.ts => interface-name-prefix.test.ts} | 2 +- ...tyle.ts => member-delimiter-style.test.ts} | 2 +- ...member-naming.ts => member-naming.test.ts} | 2 +- ...er-ordering.ts => member-ordering.test.ts} | 2 +- ...> no-angle-bracket-type-assertion.test.ts} | 2 +- ...ructor.ts => no-array-constructor.test.ts} | 2 +- ...nterface.ts => no-empty-interface.test.ts} | 2 +- ...xplicit-any.ts => no-explicit-any.test.ts} | 2 +- ...s-class.ts => no-extraneous-class.test.ts} | 2 +- ...e-types.ts => no-inferrable-types.test.ts} | 2 +- ...-misused-new.ts => no-misused-new.test.ts} | 2 +- .../{no-namespace.ts => no-namespace.test.ts} | 2 +- ...rtion.ts => no-non-null-assertion.test.ts} | 2 +- ... no-object-literal-type-assertion.test.ts} | 2 +- ...ies.ts => no-parameter-properties.test.ts} | 2 +- ...no-this-alias.ts => no-this-alias.test.ts} | 2 +- ...e.ts => no-triple-slash-reference.test.ts} | 2 +- ...no-type-alias.ts => no-type-alias.test.ts} | 2 +- ...-unused-vars.ts => no-unused-vars.test.ts} | 2 +- ...define.ts => no-use-before-define.test.ts} | 2 +- ...ar-requires.ts => no-var-requires.test.ts} | 2 +- ...-interface.ts => prefer-interface.test.ts} | 2 +- ...rd.ts => prefer-namespace-keyword.test.ts} | 2 +- ...ands.ts => restrict-plus-operands.test.ts} | 2 +- ...ing.ts => type-annotation-spacing.test.ts} | 2 +- .../tests/{util.ts => util.test.ts} | 7 +-- .../eslint-plugin/typings/eslint-rules.d.ts | 6 +-- packages/eslint-plugin/typings/eslint.d.ts | 48 +----------------- 51 files changed, 147 insertions(+), 119 deletions(-) create mode 100644 packages/eslint-plugin/tests/RuleTester.ts rename packages/eslint-plugin/tests/eslint-rules/{no-dupe-args.ts => no-dupe-args.test.ts} (94%) rename packages/eslint-plugin/tests/eslint-rules/{no-implicit-globals.ts => no-implicit-globals.test.ts} (93%) rename packages/eslint-plugin/tests/eslint-rules/{no-redeclare.ts => no-redeclare.test.ts} (94%) rename packages/eslint-plugin/tests/eslint-rules/{no-restricted-globals.ts => no-restricted-globals.test.ts} (94%) rename packages/eslint-plugin/tests/eslint-rules/{no-shadow.ts => no-shadow.test.ts} (94%) rename packages/eslint-plugin/tests/eslint-rules/{no-undef.ts => no-undef.test.ts} (97%) rename packages/eslint-plugin/tests/eslint-rules/{no-unused-vars.ts => no-unused-vars.test.ts} (94%) rename packages/eslint-plugin/tests/eslint-rules/{no-use-before-define.ts => no-use-before-define.test.ts} (95%) rename packages/eslint-plugin/tests/eslint-rules/{strict.ts => strict.test.ts} (96%) rename packages/eslint-plugin/tests/rules/{adjacent-overload-signatures.ts => adjacent-overload-signatures.test.ts} (99%) rename packages/eslint-plugin/tests/rules/{array-type.ts => array-type.test.ts} (99%) rename packages/eslint-plugin/tests/rules/{ban-types.ts => ban-types.test.ts} (99%) rename packages/eslint-plugin/tests/rules/{camelcase.ts => camelcase.test.ts} (84%) rename packages/eslint-plugin/tests/rules/{class-name-casing.ts => class-name-casing.test.ts} (98%) rename packages/eslint-plugin/tests/rules/{explicit-function-return-type.ts => explicit-function-return-type.test.ts} (98%) rename packages/eslint-plugin/tests/rules/{explicit-member-accessibility.ts => explicit-member-accessibility.test.ts} (98%) rename packages/eslint-plugin/tests/rules/{generic-type-naming.ts => generic-type-naming.test.ts} (99%) rename packages/eslint-plugin/tests/rules/{indent.ts => indent.test.ts} (100%) rename packages/eslint-plugin/tests/rules/{interface-name-prefix.ts => interface-name-prefix.test.ts} (98%) rename packages/eslint-plugin/tests/rules/{member-delimiter-style.ts => member-delimiter-style.test.ts} (99%) rename packages/eslint-plugin/tests/rules/{member-naming.ts => member-naming.test.ts} (99%) rename packages/eslint-plugin/tests/rules/{member-ordering.ts => member-ordering.test.ts} (99%) rename packages/eslint-plugin/tests/rules/{no-angle-bracket-type-assertion.ts => no-angle-bracket-type-assertion.test.ts} (98%) rename packages/eslint-plugin/tests/rules/{no-array-constructor.ts => no-array-constructor.test.ts} (98%) rename packages/eslint-plugin/tests/rules/{no-empty-interface.ts => no-empty-interface.test.ts} (97%) rename packages/eslint-plugin/tests/rules/{no-explicit-any.ts => no-explicit-any.test.ts} (99%) rename packages/eslint-plugin/tests/rules/{no-extraneous-class.ts => no-extraneous-class.test.ts} (98%) rename packages/eslint-plugin/tests/rules/{no-inferrable-types.ts => no-inferrable-types.test.ts} (99%) rename packages/eslint-plugin/tests/rules/{no-misused-new.ts => no-misused-new.test.ts} (98%) rename packages/eslint-plugin/tests/rules/{no-namespace.ts => no-namespace.test.ts} (99%) rename packages/eslint-plugin/tests/rules/{no-non-null-assertion.ts => no-non-null-assertion.test.ts} (95%) rename packages/eslint-plugin/tests/rules/{no-object-literal-type-assertion.ts => no-object-literal-type-assertion.test.ts} (98%) rename packages/eslint-plugin/tests/rules/{no-parameter-properties.ts => no-parameter-properties.test.ts} (99%) rename packages/eslint-plugin/tests/rules/{no-this-alias.ts => no-this-alias.test.ts} (98%) rename packages/eslint-plugin/tests/rules/{no-triple-slash-reference.ts => no-triple-slash-reference.test.ts} (97%) rename packages/eslint-plugin/tests/rules/{no-type-alias.ts => no-type-alias.test.ts} (99%) rename packages/eslint-plugin/tests/rules/{no-unused-vars.ts => no-unused-vars.test.ts} (99%) rename packages/eslint-plugin/tests/rules/{no-use-before-define.ts => no-use-before-define.test.ts} (99%) rename packages/eslint-plugin/tests/rules/{no-var-requires.ts => no-var-requires.test.ts} (97%) rename packages/eslint-plugin/tests/rules/{prefer-interface.ts => prefer-interface.test.ts} (97%) rename packages/eslint-plugin/tests/rules/{prefer-namespace-keyword.ts => prefer-namespace-keyword.test.ts} (98%) rename packages/eslint-plugin/tests/rules/{restrict-plus-operands.ts => restrict-plus-operands.test.ts} (99%) rename packages/eslint-plugin/tests/rules/{type-annotation-spacing.ts => type-annotation-spacing.test.ts} (99%) rename packages/eslint-plugin/tests/{util.ts => util.test.ts} (96%) diff --git a/.vscode/launch.json b/.vscode/launch.json index 0fe37133fceb..aaf6f390134e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -12,7 +12,7 @@ "program": "${workspaceFolder}/node_modules/jest/bin/jest.js", "args": [ "--colors", - "${workspaceFolder}/packages/eslint-plugin/tests/rules/${fileBasename}" + "${workspaceFolder}/packages/eslint-plugin/tests/rules/${fileBasenameNoExtension}" ], "console": "integratedTerminal", "internalConsoleOptions": "neverOpen" diff --git a/packages/eslint-plugin/jest.config.js b/packages/eslint-plugin/jest.config.js index 66423febf197..aa3dbff5b8b7 100644 --- a/packages/eslint-plugin/jest.config.js +++ b/packages/eslint-plugin/jest.config.js @@ -11,7 +11,7 @@ module.exports = { transform: { '^.+\\.tsx?$': 'ts-jest' }, - testRegex: './tests/.+\\.ts$', + testRegex: './tests/.+\\.test\\.ts$', collectCoverage: false, collectCoverageFrom: ['src/**/*.{js,jsx,ts,tsx}'], moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], diff --git a/packages/eslint-plugin/src/rules/camelcase.ts b/packages/eslint-plugin/src/rules/camelcase.ts index bfb045df2753..510e31c2e94d 100644 --- a/packages/eslint-plugin/src/rules/camelcase.ts +++ b/packages/eslint-plugin/src/rules/camelcase.ts @@ -11,15 +11,13 @@ import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -type Options = [ - { - ignoreDestructuring: boolean; - properties: 'always' | 'never'; - allow: string[]; - } -]; +interface Options { + ignoreDestructuring?: boolean; + properties?: 'always' | 'never'; + allow?: string[]; +} -const defaultOptions: Options = [ +const defaultOptions: [Required] = [ { allow: ['^UNSAFE_'], ignoreDestructuring: false, @@ -27,7 +25,7 @@ const defaultOptions: Options = [ } ]; -const rule: RuleModule<'notCamelCase', Options> = { +const rule: RuleModule<'notCamelCase', [Options]> = { meta: { type: 'suggestion', docs: { diff --git a/packages/eslint-plugin/src/util.ts b/packages/eslint-plugin/src/util.ts index c81ae20c256f..d83ee6222021 100644 --- a/packages/eslint-plugin/src/util.ts +++ b/packages/eslint-plugin/src/util.ts @@ -90,12 +90,12 @@ export function deepMerge( * @param userOptions the user opts * @returns the options with defaults */ -export function applyDefault( - defaultOptions: T, - userOptions: T | null -): T { +export function applyDefault( + defaultOptions: TDefault, + userOptions: TUser | null +): TDefault { // clone defaults - const options: T = JSON.parse(JSON.stringify(defaultOptions)); + const options: TDefault = JSON.parse(JSON.stringify(defaultOptions)); // eslint-disable-next-line eqeqeq if (userOptions == null) { diff --git a/packages/eslint-plugin/tests/RuleTester.ts b/packages/eslint-plugin/tests/RuleTester.ts new file mode 100644 index 000000000000..de87f7acb338 --- /dev/null +++ b/packages/eslint-plugin/tests/RuleTester.ts @@ -0,0 +1,50 @@ +import { RuleTester, Linter } from 'eslint'; +import RuleModule from 'ts-eslint'; + +interface ValidTestCase { + code: string; + readonly options?: TOptions; + filename?: string; + parserOptions?: Linter.ParserOptions; + settings?: Record; + parser?: string; + globals?: Record; +} + +interface InvalidTestCase + extends ValidTestCase { + errors: TestCaseError[]; + output?: string | null; +} + +interface TestCaseError { + messageId: TMessageIds; + data?: Record; + // type?: string; + line?: number; + column?: number; + // endLine?: number; + // endColumn?: number; +} + +interface RuleTesterRunTests< + TMessageIds extends string, + TOptions extends any[] +> { + // RuleTester.run also accepts strings for valid cases + valid: (ValidTestCase | string)[]; + invalid: InvalidTestCase[]; +} + +declare class RuleTesterTyped { + run( + name: string, + rule: RuleModule, + tests: RuleTesterRunTests + ): void; +} + +const RuleTesterRetyped = (RuleTester as any) as { + new (config?: any): RuleTesterTyped; +}; +export default RuleTesterRetyped; diff --git a/packages/eslint-plugin/tests/eslint-rules/no-dupe-args.ts b/packages/eslint-plugin/tests/eslint-rules/no-dupe-args.test.ts similarity index 94% rename from packages/eslint-plugin/tests/eslint-rules/no-dupe-args.ts rename to packages/eslint-plugin/tests/eslint-rules/no-dupe-args.test.ts index ed44993a0d6f..242401442324 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-dupe-args.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-dupe-args.test.ts @@ -5,7 +5,7 @@ //------------------------------------------------------------------------------ import rule from 'eslint/lib/rules/no-dupe-args'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/eslint-rules/no-implicit-globals.ts b/packages/eslint-plugin/tests/eslint-rules/no-implicit-globals.test.ts similarity index 93% rename from packages/eslint-plugin/tests/eslint-rules/no-implicit-globals.ts rename to packages/eslint-plugin/tests/eslint-rules/no-implicit-globals.test.ts index bf43b2f283c3..0add13fba05e 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-implicit-globals.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-implicit-globals.test.ts @@ -5,7 +5,7 @@ //------------------------------------------------------------------------------ import rule from 'eslint/lib/rules/no-implicit-globals'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/eslint-rules/no-redeclare.ts b/packages/eslint-plugin/tests/eslint-rules/no-redeclare.test.ts similarity index 94% rename from packages/eslint-plugin/tests/eslint-rules/no-redeclare.ts rename to packages/eslint-plugin/tests/eslint-rules/no-redeclare.test.ts index 090345c5e5fc..3a893df1dd00 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-redeclare.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-redeclare.test.ts @@ -5,7 +5,7 @@ //------------------------------------------------------------------------------ import rule from 'eslint/lib/rules/no-redeclare'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.ts b/packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.test.ts similarity index 94% rename from packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.ts rename to packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.test.ts index a6ebf38a26db..48c2babd7024 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.test.ts @@ -5,7 +5,7 @@ //------------------------------------------------------------------------------ import rule from 'eslint/lib/rules/no-restricted-globals'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/eslint-rules/no-shadow.ts b/packages/eslint-plugin/tests/eslint-rules/no-shadow.test.ts similarity index 94% rename from packages/eslint-plugin/tests/eslint-rules/no-shadow.ts rename to packages/eslint-plugin/tests/eslint-rules/no-shadow.test.ts index ff5da6cd4b31..0d65d2048872 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-shadow.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-shadow.test.ts @@ -5,7 +5,7 @@ //------------------------------------------------------------------------------ import rule from 'eslint/lib/rules/no-shadow'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/eslint-rules/no-undef.ts b/packages/eslint-plugin/tests/eslint-rules/no-undef.test.ts similarity index 97% rename from packages/eslint-plugin/tests/eslint-rules/no-undef.ts rename to packages/eslint-plugin/tests/eslint-rules/no-undef.test.ts index fb53559fa901..274a787b78a2 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-undef.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-undef.test.ts @@ -9,7 +9,7 @@ //------------------------------------------------------------------------------ import rule from 'eslint/lib/rules/no-undef'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/eslint-rules/no-unused-vars.ts b/packages/eslint-plugin/tests/eslint-rules/no-unused-vars.test.ts similarity index 94% rename from packages/eslint-plugin/tests/eslint-rules/no-unused-vars.ts rename to packages/eslint-plugin/tests/eslint-rules/no-unused-vars.test.ts index c2de51ab7065..73d9fbc06011 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-unused-vars.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-unused-vars.test.ts @@ -5,7 +5,7 @@ //------------------------------------------------------------------------------ import rule from 'eslint/lib/rules/no-unused-vars'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/eslint-rules/no-use-before-define.ts b/packages/eslint-plugin/tests/eslint-rules/no-use-before-define.test.ts similarity index 95% rename from packages/eslint-plugin/tests/eslint-rules/no-use-before-define.ts rename to packages/eslint-plugin/tests/eslint-rules/no-use-before-define.test.ts index aa2c7a26bb3a..bf346fcfa2ef 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-use-before-define.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-use-before-define.test.ts @@ -5,7 +5,7 @@ //------------------------------------------------------------------------------ import rule from 'eslint/lib/rules/no-use-before-define'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/eslint-rules/strict.ts b/packages/eslint-plugin/tests/eslint-rules/strict.test.ts similarity index 96% rename from packages/eslint-plugin/tests/eslint-rules/strict.ts rename to packages/eslint-plugin/tests/eslint-rules/strict.test.ts index 46eda6f948ed..d886a5bdb3a5 100644 --- a/packages/eslint-plugin/tests/eslint-rules/strict.ts +++ b/packages/eslint-plugin/tests/eslint-rules/strict.test.ts @@ -5,7 +5,7 @@ //------------------------------------------------------------------------------ import rule from 'eslint/lib/rules/strict'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.ts b/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.test.ts similarity index 99% rename from packages/eslint-plugin/tests/rules/adjacent-overload-signatures.ts rename to packages/eslint-plugin/tests/rules/adjacent-overload-signatures.test.ts index d583a5554628..f4b0557ec162 100644 --- a/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.ts +++ b/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.test.ts @@ -8,7 +8,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/adjacent-overload-signatures'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/array-type.ts b/packages/eslint-plugin/tests/rules/array-type.test.ts similarity index 99% rename from packages/eslint-plugin/tests/rules/array-type.ts rename to packages/eslint-plugin/tests/rules/array-type.test.ts index 561d72bf3873..0626a1b639e4 100644 --- a/packages/eslint-plugin/tests/rules/array-type.ts +++ b/packages/eslint-plugin/tests/rules/array-type.test.ts @@ -9,7 +9,8 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/array-type'; -import { RuleTester, Linter } from 'eslint'; +import RuleTester from '../RuleTester'; +import { Linter } from 'eslint'; import assert from 'assert'; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/tests/rules/ban-types.ts b/packages/eslint-plugin/tests/rules/ban-types.test.ts similarity index 99% rename from packages/eslint-plugin/tests/rules/ban-types.ts rename to packages/eslint-plugin/tests/rules/ban-types.test.ts index 3bdb2706d40e..00905e575f53 100644 --- a/packages/eslint-plugin/tests/rules/ban-types.ts +++ b/packages/eslint-plugin/tests/rules/ban-types.test.ts @@ -8,7 +8,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/ban-types'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/camelcase.ts b/packages/eslint-plugin/tests/rules/camelcase.test.ts similarity index 84% rename from packages/eslint-plugin/tests/rules/camelcase.ts rename to packages/eslint-plugin/tests/rules/camelcase.test.ts index 3a227a1198b6..12a492f993c1 100644 --- a/packages/eslint-plugin/tests/rules/camelcase.ts +++ b/packages/eslint-plugin/tests/rules/camelcase.test.ts @@ -10,7 +10,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/camelcase'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' @@ -102,7 +102,10 @@ ruleTester.run('camelcase', rule, { options: [{ properties: 'always' }], errors: [ { - message: "Identifier 'b_ar' is not in camel case.", + messageId: 'notCamelCase', + data: { + name: 'b_ar' + }, line: 1, column: 17 } @@ -113,7 +116,10 @@ ruleTester.run('camelcase', rule, { options: [{ properties: 'always' }], errors: [ { - message: "Identifier 'b_ar' is not in camel case.", + messageId: 'notCamelCase', + data: { + name: 'b_ar' + }, line: 1, column: 13 } @@ -124,7 +130,10 @@ ruleTester.run('camelcase', rule, { options: [{ properties: 'always' }], errors: [ { - message: "Identifier 'b_ar' is not in camel case.", + messageId: 'notCamelCase', + data: { + name: 'b_ar' + }, line: 1, column: 33 } @@ -135,7 +144,10 @@ ruleTester.run('camelcase', rule, { options: [{ properties: 'always' }], errors: [ { - message: "Identifier 'b_ar' is not in camel case.", + messageId: 'notCamelCase', + data: { + name: 'b_ar' + }, line: 1, column: 33 } @@ -146,7 +158,10 @@ ruleTester.run('camelcase', rule, { options: [{ properties: 'always' }], errors: [ { - message: "Identifier 'b_ar' is not in camel case.", + messageId: 'notCamelCase', + data: { + name: 'b_ar' + }, line: 1, column: 22 } @@ -157,7 +172,10 @@ ruleTester.run('camelcase', rule, { options: [{ properties: 'always' }], errors: [ { - message: "Identifier 'b_ar' is not in camel case.", + messageId: 'notCamelCase', + data: { + name: 'b_ar' + }, line: 1, column: 22 } @@ -168,7 +186,10 @@ ruleTester.run('camelcase', rule, { options: [{ properties: 'always' }], errors: [ { - message: "Identifier 'b_ar' is not in camel case.", + messageId: 'notCamelCase', + data: { + name: 'b_ar' + }, line: 1, column: 31 } @@ -179,7 +200,10 @@ ruleTester.run('camelcase', rule, { options: [{ properties: 'always' }], errors: [ { - message: "Identifier 'b_ar' is not in camel case.", + messageId: 'notCamelCase', + data: { + name: 'b_ar' + }, line: 1, column: 31 } diff --git a/packages/eslint-plugin/tests/rules/class-name-casing.ts b/packages/eslint-plugin/tests/rules/class-name-casing.test.ts similarity index 98% rename from packages/eslint-plugin/tests/rules/class-name-casing.ts rename to packages/eslint-plugin/tests/rules/class-name-casing.test.ts index baa768cd7261..a197b3ac2f64 100644 --- a/packages/eslint-plugin/tests/rules/class-name-casing.ts +++ b/packages/eslint-plugin/tests/rules/class-name-casing.test.ts @@ -9,7 +9,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/class-name-casing'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/explicit-function-return-type.ts b/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts similarity index 98% rename from packages/eslint-plugin/tests/rules/explicit-function-return-type.ts rename to packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts index f8343bb1400b..bf6009775f49 100644 --- a/packages/eslint-plugin/tests/rules/explicit-function-return-type.ts +++ b/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts @@ -8,7 +8,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/explicit-function-return-type'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/explicit-member-accessibility.ts b/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts similarity index 98% rename from packages/eslint-plugin/tests/rules/explicit-member-accessibility.ts rename to packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts index eb3ee827fe61..25809a0482a0 100644 --- a/packages/eslint-plugin/tests/rules/explicit-member-accessibility.ts +++ b/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts @@ -8,7 +8,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/explicit-member-accessibility'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/generic-type-naming.ts b/packages/eslint-plugin/tests/rules/generic-type-naming.test.ts similarity index 99% rename from packages/eslint-plugin/tests/rules/generic-type-naming.ts rename to packages/eslint-plugin/tests/rules/generic-type-naming.test.ts index 152ff9e99f12..9231dcf88701 100644 --- a/packages/eslint-plugin/tests/rules/generic-type-naming.ts +++ b/packages/eslint-plugin/tests/rules/generic-type-naming.test.ts @@ -7,7 +7,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/generic-type-naming'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/indent.ts b/packages/eslint-plugin/tests/rules/indent.test.ts similarity index 100% rename from packages/eslint-plugin/tests/rules/indent.ts rename to packages/eslint-plugin/tests/rules/indent.test.ts diff --git a/packages/eslint-plugin/tests/rules/interface-name-prefix.ts b/packages/eslint-plugin/tests/rules/interface-name-prefix.test.ts similarity index 98% rename from packages/eslint-plugin/tests/rules/interface-name-prefix.ts rename to packages/eslint-plugin/tests/rules/interface-name-prefix.test.ts index 4cf3734661e6..dbbb4214d269 100644 --- a/packages/eslint-plugin/tests/rules/interface-name-prefix.ts +++ b/packages/eslint-plugin/tests/rules/interface-name-prefix.test.ts @@ -8,7 +8,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/interface-name-prefix'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/member-delimiter-style.ts b/packages/eslint-plugin/tests/rules/member-delimiter-style.test.ts similarity index 99% rename from packages/eslint-plugin/tests/rules/member-delimiter-style.ts rename to packages/eslint-plugin/tests/rules/member-delimiter-style.test.ts index 07b7c442d81d..d4ba193a4cef 100644 --- a/packages/eslint-plugin/tests/rules/member-delimiter-style.ts +++ b/packages/eslint-plugin/tests/rules/member-delimiter-style.test.ts @@ -9,7 +9,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/member-delimiter-style'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/member-naming.ts b/packages/eslint-plugin/tests/rules/member-naming.test.ts similarity index 99% rename from packages/eslint-plugin/tests/rules/member-naming.ts rename to packages/eslint-plugin/tests/rules/member-naming.test.ts index 0752f3e4f8b2..aefe3eb4a469 100644 --- a/packages/eslint-plugin/tests/rules/member-naming.ts +++ b/packages/eslint-plugin/tests/rules/member-naming.test.ts @@ -8,7 +8,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/member-naming'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/member-ordering.ts b/packages/eslint-plugin/tests/rules/member-ordering.test.ts similarity index 99% rename from packages/eslint-plugin/tests/rules/member-ordering.ts rename to packages/eslint-plugin/tests/rules/member-ordering.test.ts index d2c1ef3e0218..d6e9f85d3218 100644 --- a/packages/eslint-plugin/tests/rules/member-ordering.ts +++ b/packages/eslint-plugin/tests/rules/member-ordering.test.ts @@ -8,7 +8,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/member-ordering'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/no-angle-bracket-type-assertion.ts b/packages/eslint-plugin/tests/rules/no-angle-bracket-type-assertion.test.ts similarity index 98% rename from packages/eslint-plugin/tests/rules/no-angle-bracket-type-assertion.ts rename to packages/eslint-plugin/tests/rules/no-angle-bracket-type-assertion.test.ts index 111120078bd8..3db2ad84958f 100644 --- a/packages/eslint-plugin/tests/rules/no-angle-bracket-type-assertion.ts +++ b/packages/eslint-plugin/tests/rules/no-angle-bracket-type-assertion.test.ts @@ -8,7 +8,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/no-angle-bracket-type-assertion'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/no-array-constructor.ts b/packages/eslint-plugin/tests/rules/no-array-constructor.test.ts similarity index 98% rename from packages/eslint-plugin/tests/rules/no-array-constructor.ts rename to packages/eslint-plugin/tests/rules/no-array-constructor.test.ts index 4e21e4000329..b87857703844 100644 --- a/packages/eslint-plugin/tests/rules/no-array-constructor.ts +++ b/packages/eslint-plugin/tests/rules/no-array-constructor.test.ts @@ -9,7 +9,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/no-array-constructor'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/no-empty-interface.ts b/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts similarity index 97% rename from packages/eslint-plugin/tests/rules/no-empty-interface.ts rename to packages/eslint-plugin/tests/rules/no-empty-interface.test.ts index ef7563a6147d..1af52a3299c9 100644 --- a/packages/eslint-plugin/tests/rules/no-empty-interface.ts +++ b/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts @@ -8,7 +8,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/no-empty-interface'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/no-explicit-any.ts b/packages/eslint-plugin/tests/rules/no-explicit-any.test.ts similarity index 99% rename from packages/eslint-plugin/tests/rules/no-explicit-any.ts rename to packages/eslint-plugin/tests/rules/no-explicit-any.test.ts index 10ee49ae69df..c1f7f4aa56ff 100644 --- a/packages/eslint-plugin/tests/rules/no-explicit-any.ts +++ b/packages/eslint-plugin/tests/rules/no-explicit-any.test.ts @@ -8,7 +8,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/no-explicit-any'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/no-extraneous-class.ts b/packages/eslint-plugin/tests/rules/no-extraneous-class.test.ts similarity index 98% rename from packages/eslint-plugin/tests/rules/no-extraneous-class.ts rename to packages/eslint-plugin/tests/rules/no-extraneous-class.test.ts index 059a18c791a1..6a895e66f272 100644 --- a/packages/eslint-plugin/tests/rules/no-extraneous-class.ts +++ b/packages/eslint-plugin/tests/rules/no-extraneous-class.test.ts @@ -9,7 +9,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/no-extraneous-class'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; const empty = { messageId: 'empty', type: 'Identifier' }; const onlyStatic = { messageId: 'onlyStatic', type: 'Identifier' }; diff --git a/packages/eslint-plugin/tests/rules/no-inferrable-types.ts b/packages/eslint-plugin/tests/rules/no-inferrable-types.test.ts similarity index 99% rename from packages/eslint-plugin/tests/rules/no-inferrable-types.ts rename to packages/eslint-plugin/tests/rules/no-inferrable-types.test.ts index 874bf1238ec1..27bacd0c05a8 100644 --- a/packages/eslint-plugin/tests/rules/no-inferrable-types.ts +++ b/packages/eslint-plugin/tests/rules/no-inferrable-types.test.ts @@ -8,7 +8,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/no-inferrable-types'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/no-misused-new.ts b/packages/eslint-plugin/tests/rules/no-misused-new.test.ts similarity index 98% rename from packages/eslint-plugin/tests/rules/no-misused-new.ts rename to packages/eslint-plugin/tests/rules/no-misused-new.test.ts index 905c74c37c6c..708b8a588a0a 100644 --- a/packages/eslint-plugin/tests/rules/no-misused-new.ts +++ b/packages/eslint-plugin/tests/rules/no-misused-new.test.ts @@ -8,7 +8,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/no-misused-new'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/no-namespace.ts b/packages/eslint-plugin/tests/rules/no-namespace.test.ts similarity index 99% rename from packages/eslint-plugin/tests/rules/no-namespace.ts rename to packages/eslint-plugin/tests/rules/no-namespace.test.ts index 75047aff510a..951c22c69201 100644 --- a/packages/eslint-plugin/tests/rules/no-namespace.ts +++ b/packages/eslint-plugin/tests/rules/no-namespace.test.ts @@ -8,7 +8,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/no-namespace'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/no-non-null-assertion.ts b/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts similarity index 95% rename from packages/eslint-plugin/tests/rules/no-non-null-assertion.ts rename to packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts index 511d222405d0..5840826bd2e0 100644 --- a/packages/eslint-plugin/tests/rules/no-non-null-assertion.ts +++ b/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts @@ -8,7 +8,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/no-non-null-assertion'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/no-object-literal-type-assertion.ts b/packages/eslint-plugin/tests/rules/no-object-literal-type-assertion.test.ts similarity index 98% rename from packages/eslint-plugin/tests/rules/no-object-literal-type-assertion.ts rename to packages/eslint-plugin/tests/rules/no-object-literal-type-assertion.test.ts index c5d5a6d8f6f7..f17624d196e9 100644 --- a/packages/eslint-plugin/tests/rules/no-object-literal-type-assertion.ts +++ b/packages/eslint-plugin/tests/rules/no-object-literal-type-assertion.test.ts @@ -8,7 +8,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/no-object-literal-type-assertion'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/no-parameter-properties.ts b/packages/eslint-plugin/tests/rules/no-parameter-properties.test.ts similarity index 99% rename from packages/eslint-plugin/tests/rules/no-parameter-properties.ts rename to packages/eslint-plugin/tests/rules/no-parameter-properties.test.ts index 457cda8a4c89..0a5922aabbdd 100644 --- a/packages/eslint-plugin/tests/rules/no-parameter-properties.ts +++ b/packages/eslint-plugin/tests/rules/no-parameter-properties.test.ts @@ -8,7 +8,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/no-parameter-properties'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/no-this-alias.ts b/packages/eslint-plugin/tests/rules/no-this-alias.test.ts similarity index 98% rename from packages/eslint-plugin/tests/rules/no-this-alias.ts rename to packages/eslint-plugin/tests/rules/no-this-alias.test.ts index 0a665700f38c..6b27dd55bef0 100644 --- a/packages/eslint-plugin/tests/rules/no-this-alias.ts +++ b/packages/eslint-plugin/tests/rules/no-this-alias.test.ts @@ -9,7 +9,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/no-this-alias'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; const idError = { messageId: 'thisAssignment', type: 'Identifier' }; const destructureError = { diff --git a/packages/eslint-plugin/tests/rules/no-triple-slash-reference.ts b/packages/eslint-plugin/tests/rules/no-triple-slash-reference.test.ts similarity index 97% rename from packages/eslint-plugin/tests/rules/no-triple-slash-reference.ts rename to packages/eslint-plugin/tests/rules/no-triple-slash-reference.test.ts index f33b2bc1a9d7..80eb43061cd0 100644 --- a/packages/eslint-plugin/tests/rules/no-triple-slash-reference.ts +++ b/packages/eslint-plugin/tests/rules/no-triple-slash-reference.test.ts @@ -8,7 +8,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/no-triple-slash-reference'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/no-type-alias.ts b/packages/eslint-plugin/tests/rules/no-type-alias.test.ts similarity index 99% rename from packages/eslint-plugin/tests/rules/no-type-alias.ts rename to packages/eslint-plugin/tests/rules/no-type-alias.test.ts index 8dac4f0c2d9f..5b097e8973d9 100644 --- a/packages/eslint-plugin/tests/rules/no-type-alias.ts +++ b/packages/eslint-plugin/tests/rules/no-type-alias.test.ts @@ -8,7 +8,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/no-type-alias'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/no-unused-vars.ts b/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts similarity index 99% rename from packages/eslint-plugin/tests/rules/no-unused-vars.ts rename to packages/eslint-plugin/tests/rules/no-unused-vars.test.ts index c99b7caf5648..5fed5a6a5d1c 100644 --- a/packages/eslint-plugin/tests/rules/no-unused-vars.ts +++ b/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts @@ -8,7 +8,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/no-unused-vars'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/rules/no-use-before-define.ts b/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts similarity index 99% rename from packages/eslint-plugin/tests/rules/no-use-before-define.ts rename to packages/eslint-plugin/tests/rules/no-use-before-define.test.ts index 674884dae2f1..bfef6af5d520 100644 --- a/packages/eslint-plugin/tests/rules/no-use-before-define.ts +++ b/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts @@ -9,7 +9,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/no-use-before-define'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/no-var-requires.ts b/packages/eslint-plugin/tests/rules/no-var-requires.test.ts similarity index 97% rename from packages/eslint-plugin/tests/rules/no-var-requires.ts rename to packages/eslint-plugin/tests/rules/no-var-requires.test.ts index 4dbd769c6475..5a1bc700ea92 100644 --- a/packages/eslint-plugin/tests/rules/no-var-requires.ts +++ b/packages/eslint-plugin/tests/rules/no-var-requires.test.ts @@ -8,7 +8,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/no-var-requires'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/prefer-interface.ts b/packages/eslint-plugin/tests/rules/prefer-interface.test.ts similarity index 97% rename from packages/eslint-plugin/tests/rules/prefer-interface.ts rename to packages/eslint-plugin/tests/rules/prefer-interface.test.ts index 9a770b5e6eeb..f48cb2f57cb3 100644 --- a/packages/eslint-plugin/tests/rules/prefer-interface.ts +++ b/packages/eslint-plugin/tests/rules/prefer-interface.test.ts @@ -8,7 +8,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/prefer-interface'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/prefer-namespace-keyword.ts b/packages/eslint-plugin/tests/rules/prefer-namespace-keyword.test.ts similarity index 98% rename from packages/eslint-plugin/tests/rules/prefer-namespace-keyword.ts rename to packages/eslint-plugin/tests/rules/prefer-namespace-keyword.test.ts index 9ff5e4b0db47..4a4e5253a7b0 100644 --- a/packages/eslint-plugin/tests/rules/prefer-namespace-keyword.ts +++ b/packages/eslint-plugin/tests/rules/prefer-namespace-keyword.test.ts @@ -9,7 +9,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/prefer-namespace-keyword'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/restrict-plus-operands.ts b/packages/eslint-plugin/tests/rules/restrict-plus-operands.test.ts similarity index 99% rename from packages/eslint-plugin/tests/rules/restrict-plus-operands.ts rename to packages/eslint-plugin/tests/rules/restrict-plus-operands.test.ts index 17da3c49b7b8..e1a65a87bb40 100644 --- a/packages/eslint-plugin/tests/rules/restrict-plus-operands.ts +++ b/packages/eslint-plugin/tests/rules/restrict-plus-operands.test.ts @@ -10,7 +10,7 @@ const path = require('path'); import rule from '../../src/rules/restrict-plus-operands'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/type-annotation-spacing.ts b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts similarity index 99% rename from packages/eslint-plugin/tests/rules/type-annotation-spacing.ts rename to packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts index d5d43d4b0242..26e7b832cf66 100644 --- a/packages/eslint-plugin/tests/rules/type-annotation-spacing.ts +++ b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts @@ -8,7 +8,7 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/type-annotation-spacing'; -import { RuleTester } from 'eslint'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/util.ts b/packages/eslint-plugin/tests/util.test.ts similarity index 96% rename from packages/eslint-plugin/tests/util.ts rename to packages/eslint-plugin/tests/util.test.ts index 4781d86a79e3..0fa29aec7a1f 100644 --- a/packages/eslint-plugin/tests/util.ts +++ b/packages/eslint-plugin/tests/util.test.ts @@ -143,18 +143,19 @@ describe('applyDefault', () => { it('returns applies a deepMerge to each element in the array', () => { const defaults = [ { - prop: 'setting1' + prop: 'setting1', + other: 'other' }, { prop: 'setting2' } - ]; + ] as Record[]; const user = [ { prop: 'new', other: 'something' } - ]; + ] as Record[]; const result = util.applyDefault(defaults, user); assert.deepStrictEqual(result, [ diff --git a/packages/eslint-plugin/typings/eslint-rules.d.ts b/packages/eslint-plugin/typings/eslint-rules.d.ts index cbd44063c53f..ca45537c0a3c 100644 --- a/packages/eslint-plugin/typings/eslint-rules.d.ts +++ b/packages/eslint-plugin/typings/eslint-rules.d.ts @@ -13,9 +13,9 @@ declare module 'eslint/lib/rules/camelcase' { 'notCamelCase', [ { - ignoreDestructuring: boolean; - properties: 'always' | 'never'; - allow: string[]; + ignoreDestructuring?: boolean; + properties?: 'always' | 'never'; + allow?: string[]; } ], { diff --git a/packages/eslint-plugin/typings/eslint.d.ts b/packages/eslint-plugin/typings/eslint.d.ts index 56b5ff3d92f5..30ee0180c31d 100644 --- a/packages/eslint-plugin/typings/eslint.d.ts +++ b/packages/eslint-plugin/typings/eslint.d.ts @@ -1,55 +1,9 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ - // module augmentation is weird -import { RuleTester, Scope } from 'eslint'; -import { TSESTree } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; +import { Scope } from 'eslint'; declare module 'eslint' { namespace Scope { interface Variable { eslintUsed: boolean; } } - - interface ValidTestCase { - code: string; - options?: TOptions; - filename?: string; - parserOptions?: Linter.ParserOptions; - settings?: Record; - parser?: string; - globals?: Record; - } - - interface InvalidTestCase - extends ValidTestCase { - errors: TestCaseError[]; - output?: string | null; - } - - interface TestCaseError { - messageId: TMessageIds; - data?: Record; - // type?: string; - line?: number; - column?: number; - // endLine?: number; - // endColumn?: number; - } - - interface RuleTesterRunTests< - TMessageIds extends string, - TOptions extends any[] - > { - // RuleTester.run also accepts strings for valid cases - valid: (ValidTestCase | string)[]; - invalid: InvalidTestCase[]; - } - interface RuleTester { - run( - name: string, - rule: RuleModule, - tests: RuleTesterRunTests - ): void; - } } From e8fc81736c6c1fb9da110b18047a889bf3e1cafa Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Thu, 31 Jan 2019 17:26:38 -0800 Subject: [PATCH 30/92] class-name-casing --- .../src/rules/class-name-casing.ts | 40 ++++++++++------ .../tests/rules/class-name-casing.test.ts | 48 +++++++++++++++---- 2 files changed, 65 insertions(+), 23 deletions(-) diff --git a/packages/eslint-plugin/src/rules/class-name-casing.ts b/packages/eslint-plugin/src/rules/class-name-casing.ts index f9cc12f46993..e035c1c06004 100644 --- a/packages/eslint-plugin/src/rules/class-name-casing.ts +++ b/packages/eslint-plugin/src/rules/class-name-casing.ts @@ -6,12 +6,13 @@ import RuleModule from 'ts-eslint'; import * as util from '../util'; +import { TSESTree } from '@typescript-eslint/typescript-estree'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -const rule: RuleModule = { +const rule: RuleModule<'notPascalCased', []> = { meta: { type: 'suggestion', docs: { @@ -21,6 +22,9 @@ const rule: RuleModule = { url: util.metaDocsUrl('class-name-casing'), recommended: 'error' }, + messages: { + notPascalCased: "{{friendlyName}} '{{name}}' must be PascalCased." + }, schema: [] }, @@ -41,12 +45,10 @@ const rule: RuleModule = { /** * Report a class declaration as invalid - * @param {Node} decl The declaration - * @param {Node} [id=classDecl.id] The name of the declaration + * @param decl The declaration + * @param id The name of the declaration */ - function report(decl, id): void { - const resolvedId = id || decl.id; - + function report(decl: TSESTree.Node, id: TSESTree.Identifier): void { let friendlyName; switch (decl.type) { @@ -62,11 +64,11 @@ const rule: RuleModule = { } context.report({ - node: resolvedId, - message: "{{friendlyName}} '{{name}}' must be PascalCased.", + node: id, + messageId: 'notPascalCased', data: { friendlyName, - name: resolvedId.name + name: id.name } }); } @@ -76,17 +78,25 @@ const rule: RuleModule = { //---------------------------------------------------------------------- return { - 'ClassDeclaration, TSInterfaceDeclaration, ClassExpression'(node) { + 'ClassDeclaration, TSInterfaceDeclaration, ClassExpression'( + node: + | TSESTree.ClassDeclaration + | TSESTree.TSInterfaceDeclaration + | TSESTree.ClassExpression + ) { // class expressions (i.e. export default class {}) are OK if (node.id && !isPascalCase(node.id.name)) { - report(node); + report(node, node.id); } }, - "VariableDeclarator[init.type='ClassExpression']"(node) { - const id = node.id; + "VariableDeclarator[init.type='ClassExpression']"( + node: TSESTree.VariableDeclarator + ) { + const id = node.id as TSESTree.Identifier; + const nodeInit = node.init as TSESTree.ClassExpression; - if (id && !node.init.id && !isPascalCase(id.name)) { - report(node.init, id); + if (id && !nodeInit.id && !isPascalCase(id.name)) { + report(nodeInit, id); } } }; diff --git a/packages/eslint-plugin/tests/rules/class-name-casing.test.ts b/packages/eslint-plugin/tests/rules/class-name-casing.test.ts index a197b3ac2f64..980a609e74aa 100644 --- a/packages/eslint-plugin/tests/rules/class-name-casing.test.ts +++ b/packages/eslint-plugin/tests/rules/class-name-casing.test.ts @@ -40,7 +40,11 @@ ruleTester.run('class-name-casing', rule, { code: 'class invalidClassName {}', errors: [ { - message: "Class 'invalidClassName' must be PascalCased.", + messageId: 'notPascalCased', + data: { + friendlyName: 'Class', + name: 'invalidClassName' + }, line: 1, column: 7 } @@ -50,7 +54,11 @@ ruleTester.run('class-name-casing', rule, { code: 'class Another_Invalid_Class_Name {}', errors: [ { - message: "Class 'Another_Invalid_Class_Name' must be PascalCased.", + messageId: 'notPascalCased', + data: { + friendlyName: 'Class', + name: 'Another_Invalid_Class_Name' + }, line: 1, column: 7 } @@ -60,7 +68,11 @@ ruleTester.run('class-name-casing', rule, { code: 'var foo = class {};', errors: [ { - message: "Class 'foo' must be PascalCased.", + messageId: 'notPascalCased', + data: { + friendlyName: 'Class', + name: 'foo' + }, line: 1, column: 5 } @@ -70,7 +82,11 @@ ruleTester.run('class-name-casing', rule, { code: 'const foo = class {};', errors: [ { - message: "Class 'foo' must be PascalCased.", + messageId: 'notPascalCased', + data: { + friendlyName: 'Class', + name: 'foo' + }, line: 1, column: 7 } @@ -80,7 +96,11 @@ ruleTester.run('class-name-casing', rule, { code: 'var bar = class invalidName {}', errors: [ { - message: "Class 'invalidName' must be PascalCased.", + messageId: 'notPascalCased', + data: { + friendlyName: 'Class', + name: 'invalidName' + }, line: 1, column: 17 } @@ -90,7 +110,11 @@ ruleTester.run('class-name-casing', rule, { code: 'interface someInterface {}', errors: [ { - message: "Interface 'someInterface' must be PascalCased.", + messageId: 'notPascalCased', + data: { + friendlyName: 'Interface', + name: 'someInterface' + }, line: 1, column: 11 } @@ -100,7 +124,11 @@ ruleTester.run('class-name-casing', rule, { code: 'abstract class invalidClassName {}', errors: [ { - message: "Abstract class 'invalidClassName' must be PascalCased.", + messageId: 'notPascalCased', + data: { + friendlyName: 'Abstract class', + name: 'invalidClassName' + }, line: 1, column: 16 } @@ -110,7 +138,11 @@ ruleTester.run('class-name-casing', rule, { code: 'declare class invalidClassName {}', errors: [ { - message: "Class 'invalidClassName' must be PascalCased.", + messageId: 'notPascalCased', + data: { + friendlyName: 'Class', + name: 'invalidClassName' + }, line: 1, column: 15 } From 1ab295c972d466ec7323daa8f9f75f09f02c9be3 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Thu, 31 Jan 2019 17:33:02 -0800 Subject: [PATCH 31/92] explicit-function-return-type --- .../rules/explicit-function-return-type.ts | 47 ++++++++++++++----- .../explicit-function-return-type.test.ts | 14 +++--- 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts index 318026d70afd..13f4b93b1b50 100644 --- a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts +++ b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts @@ -5,27 +5,36 @@ import RuleModule from 'ts-eslint'; import * as util from '../util'; +import { TSESTree } from '@typescript-eslint/typescript-estree'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ +type Options = [ + { + allowExpressions?: boolean; + } +]; -const defaultOptions = [ +const defaultOptions: Options = [ { allowExpressions: true } ]; -const rule: RuleModule = { +const rule: RuleModule<'missingReturnType', Options> = { meta: { type: 'problem', docs: { description: 'Require explicit return types on functions and class methods', - category: 'TypeScript', + category: 'Stylistic Issues', url: util.metaDocsUrl('explicit-function-return-type'), recommended: 'warn' }, + messages: { + missingReturnType: 'Missing return type on function.' + }, schema: [ { type: 'object', @@ -48,9 +57,9 @@ const rule: RuleModule = { /** * Checks if the parent of a function expression is a constructor. - * @param {ASTNode} parent The parent of a function expression node + * @param parent The parent of a function expression node */ - function isConstructor(parent): boolean { + function isConstructor(parent: TSESTree.Node): boolean { return ( parent.type === 'MethodDefinition' && parent.kind === 'constructor' ); @@ -58,26 +67,32 @@ const rule: RuleModule = { /** * Checks if the parent of a function expression is a setter. - * @param {ASTNode} parent The parent of a function expression node + * @param parent The parent of a function expression node */ - function isSetter(parent): boolean { + function isSetter(parent: TSESTree.Node): boolean { return parent.type === 'MethodDefinition' && parent.kind === 'set'; } /** * Checks if a function declaration/expression has a return type. - * @param {ASTNode} node The node representing a function. + * @param node The node representing a function. */ - function checkFunctionReturnType(node): void { + function checkFunctionReturnType( + node: + | TSESTree.ArrowFunctionExpression + | TSESTree.FunctionDeclaration + | TSESTree.FunctionExpression + ): void { if ( !node.returnType && + node.parent && !isConstructor(node.parent) && !isSetter(node.parent) && util.isTypescript(context.getFilename()) ) { context.report({ node, - message: `Missing return type on function.` + messageId: 'missingReturnType' }); } } @@ -86,9 +101,15 @@ const rule: RuleModule = { * Checks if a function declaration/expression has a return type. * @param {ASTNode} node The node representing a function. */ - function checkFunctionExpressionReturnType(node): void { + function checkFunctionExpressionReturnType( + node: + | TSESTree.ArrowFunctionExpression + | TSESTree.FunctionDeclaration + | TSESTree.FunctionExpression + ): void { if ( options.allowExpressions && + node.parent && node.parent.type !== 'VariableDeclarator' && node.parent.type !== 'MethodDefinition' ) { @@ -102,9 +123,9 @@ const rule: RuleModule = { // Public //---------------------------------------------------------------------- return { + ArrowFunctionExpression: checkFunctionExpressionReturnType, FunctionDeclaration: checkFunctionReturnType, - FunctionExpression: checkFunctionExpressionReturnType, - ArrowFunctionExpression: checkFunctionExpressionReturnType + FunctionExpression: checkFunctionExpressionReturnType }; } }; diff --git a/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts b/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts index bf6009775f49..d17114dac7bf 100644 --- a/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts +++ b/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts @@ -116,7 +116,7 @@ function test() { `, errors: [ { - message: 'Missing return type on function.', + messageId: 'missingReturnType', line: 2, column: 1 } @@ -131,7 +131,7 @@ var fn = function() { `, errors: [ { - message: 'Missing return type on function.', + messageId: 'missingReturnType', line: 2, column: 10 } @@ -144,7 +144,7 @@ var arrowFn = () => 'test'; `, errors: [ { - message: 'Missing return type on function.', + messageId: 'missingReturnType', line: 2, column: 15 } @@ -166,12 +166,12 @@ class Test { `, errors: [ { - message: 'Missing return type on function.', + messageId: 'missingReturnType', line: 4, column: 11 }, { - message: 'Missing return type on function.', + messageId: 'missingReturnType', line: 8, column: 9 } @@ -183,7 +183,7 @@ class Test { options: [{ allowExpressions: true }], errors: [ { - message: 'Missing return type on function.', + messageId: 'missingReturnType', line: 1, column: 13 } @@ -195,7 +195,7 @@ class Test { options: [{ allowExpressions: true }], errors: [ { - message: 'Missing return type on function.', + messageId: 'missingReturnType', line: 1, column: 13 } From 35ab1bb12d465ba571e902ac526f36bde77ca267 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Thu, 31 Jan 2019 17:58:51 -0800 Subject: [PATCH 32/92] explicit-member-accessibility --- .../rules/explicit-function-return-type.ts | 2 +- .../rules/explicit-member-accessibility.ts | 33 ++++++++++++------- packages/eslint-plugin/src/tsestree-utils.ts | 14 ++++++++ .../explicit-member-accessibility.test.ts | 24 +++++++++++--- 4 files changed, 57 insertions(+), 16 deletions(-) create mode 100644 packages/eslint-plugin/src/tsestree-utils.ts diff --git a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts index 13f4b93b1b50..2c3cc1b171cd 100644 --- a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts +++ b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts @@ -3,9 +3,9 @@ * @author Scott O'Hara */ +import { TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; -import { TSESTree } from '@typescript-eslint/typescript-estree'; //------------------------------------------------------------------------------ // Rule Definition diff --git a/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts index df73a897edd0..bc2e45ec3873 100644 --- a/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts +++ b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts @@ -3,24 +3,30 @@ * @author Danny Fritz */ +import { TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; +import { getNameFromPropertyName } from '../tsestree-utils'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -const rule: RuleModule = { +const rule: RuleModule<'missingAccessibility', []> = { meta: { type: 'problem', docs: { description: 'Require explicit accessibility modifiers on class properties and methods', extraDescription: [util.tslintRule('member-access')], - category: 'TypeScript', + category: 'Best Practices', url: util.metaDocsUrl('explicit-member-accessibility'), recommended: 'error' }, + messages: { + missingAccessibility: + 'Missing accessibility modifier on {{type}} {{name}}.' + }, schema: [] }, @@ -31,19 +37,21 @@ const rule: RuleModule = { /** * Checks if a method declaration has an accessibility modifier. - * @param {ASTNode} methodDefinition The node representing a MethodDefinition. + * @param methodDefinition The node representing a MethodDefinition. */ - function checkMethodAccessibilityModifier(methodDefinition): void { + function checkMethodAccessibilityModifier( + methodDefinition: TSESTree.MethodDefinition + ): void { if ( !methodDefinition.accessibility && util.isTypescript(context.getFilename()) ) { context.report({ node: methodDefinition, - message: - 'Missing accessibility modifier on method definition {{name}}.', + messageId: 'missingAccessibility', data: { - name: methodDefinition.key.name + type: 'method definition', + name: getNameFromPropertyName(methodDefinition.key) } }); } @@ -51,18 +59,21 @@ const rule: RuleModule = { /** * Checks if property has an accessibility modifier. - * @param {ASTNode} classProperty The node representing a ClassProperty. + * @param classProperty The node representing a ClassProperty. */ - function checkPropertyAccessibilityModifier(classProperty): void { + function checkPropertyAccessibilityModifier( + classProperty: TSESTree.ClassProperty + ): void { if ( !classProperty.accessibility && util.isTypescript(context.getFilename()) ) { context.report({ node: classProperty, - message: 'Missing accessibility modifier on class property {{name}}.', + messageId: 'missingAccessibility', data: { - name: classProperty.key.name + type: 'class property', + name: getNameFromPropertyName(classProperty.key) } }); } diff --git a/packages/eslint-plugin/src/tsestree-utils.ts b/packages/eslint-plugin/src/tsestree-utils.ts new file mode 100644 index 000000000000..92cbd839611d --- /dev/null +++ b/packages/eslint-plugin/src/tsestree-utils.ts @@ -0,0 +1,14 @@ +/** + * @fileoverview Utilities for working with union types exported by the TSESTree types + */ + +import { TSESTree } from '@typescript-eslint/typescript-estree'; + +export function getNameFromPropertyName( + propertyName: TSESTree.PropertyName +): string { + if (propertyName.type === 'Identifier') { + return propertyName.name; + } + return propertyName.value; +} diff --git a/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts b/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts index 25809a0482a0..b25dfc7e2b37 100644 --- a/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts +++ b/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts @@ -66,7 +66,11 @@ class Test { `, errors: [ { - message: 'Missing accessibility modifier on class property x.', + messageId: 'missingAccessibility', + data: { + type: 'class property', + name: 'x' + }, line: 3, column: 3 } @@ -84,7 +88,11 @@ class Test { `, errors: [ { - message: 'Missing accessibility modifier on method definition getX.', + messageId: 'missingAccessibility', + data: { + type: 'method definition', + name: 'getX' + }, line: 4, column: 3 } @@ -102,12 +110,20 @@ class Test { `, errors: [ { - message: 'Missing accessibility modifier on class property x.', + messageId: 'missingAccessibility', + data: { + type: 'class property', + name: 'x' + }, line: 3, column: 3 }, { - message: 'Missing accessibility modifier on method definition getX.', + messageId: 'missingAccessibility', + data: { + type: 'method definition', + name: 'getX' + }, line: 4, column: 3 } From 64ca20b80fa9591909bad1201ecf6fa800c86b7b Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Thu, 31 Jan 2019 18:02:39 -0800 Subject: [PATCH 33/92] generic-type-naming --- .../src/rules/generic-type-naming.ts | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/packages/eslint-plugin/src/rules/generic-type-naming.ts b/packages/eslint-plugin/src/rules/generic-type-naming.ts index e0de2968173c..f04a414c3e79 100644 --- a/packages/eslint-plugin/src/rules/generic-type-naming.ts +++ b/packages/eslint-plugin/src/rules/generic-type-naming.ts @@ -2,20 +2,24 @@ * @fileoverview Enforces naming of generic type variables. */ +import { TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; -const defaultOptions = [ +type Options = [string]; + +const defaultOptions: Options = [ // Matches: T , TA , TAbc , TA1Bca , T1 , T2 '^T([A-Z0-9][a-zA-Z0-9]*){0,1}$' ]; -const rule: RuleModule = { +const rule: RuleModule<'paramNotMatchRule', Options> = { meta: { type: 'suggestion', docs: { description: 'Enforces naming of generic type variables', - category: 'TypeScript', + category: 'Stylistic Issues', + recommended: false, url: util.metaDocsUrl('generic-type-naming') }, messages: { @@ -25,8 +29,7 @@ const rule: RuleModule = { { type: 'string' } - ], - recommended: 'error' + ] }, create(context) { @@ -34,17 +37,17 @@ const rule: RuleModule = { const regex = new RegExp(rule); return { - TSTypeParameter(node) { - const name = - node.name && node.name.type === 'Identifier' ? node.name.name : null; + TSTypeParameter(node: TSESTree.TSTypeParameter) { + const name = node.name.name; if (name && !regex.test(name)) { - const data = { name, rule }; - context.report({ node, messageId: 'paramNotMatchRule', - data + data: { + name, + rule + } }); } } From 14c0568b205f362459d3c45d61b56795bfcc7b71 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Thu, 31 Jan 2019 21:45:49 -0800 Subject: [PATCH 34/92] indent THIS ONE REALLY SUCKED --- .vscode/launch.json | 1 + packages/eslint-plugin/package.json | 2 +- packages/eslint-plugin/src/rules/camelcase.ts | 17 +- packages/eslint-plugin/src/rules/indent.ts | 173 +++++--- packages/eslint-plugin/src/tsestree-utils.ts | 15 + packages/eslint-plugin/tests/RuleTester.ts | 8 +- .../eslint-plugin/tests/rules/indent.test.ts | 417 +++++++++++++++--- .../eslint-plugin/typings/eslint-rules.d.ts | 102 ++++- packages/typescript-estree/src/typedefs.ts | 58 +-- yarn.lock | 43 -- 10 files changed, 618 insertions(+), 218 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index aaf6f390134e..693f6f1ac541 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -12,6 +12,7 @@ "program": "${workspaceFolder}/node_modules/jest/bin/jest.js", "args": [ "--colors", + "--runInBand", "${workspaceFolder}/packages/eslint-plugin/tests/rules/${fileBasenameNoExtension}" ], "console": "integratedTerminal", diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 7d8e52d90fb8..9042e5c1fde3 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -31,7 +31,7 @@ "requireindex": "^1.2.0" }, "devDependencies": { - "eslint": "^5.9.0", + "eslint": "^5.12.1", "eslint-docs": "^0.2.6", "ts-node": "^8.0.1", "@typescript-eslint/typescript-estree": "1.1.0" diff --git a/packages/eslint-plugin/src/rules/camelcase.ts b/packages/eslint-plugin/src/rules/camelcase.ts index 510e31c2e94d..b7b6a5ccd1f7 100644 --- a/packages/eslint-plugin/src/rules/camelcase.ts +++ b/packages/eslint-plugin/src/rules/camelcase.ts @@ -7,17 +7,18 @@ import { TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import baseRule from 'eslint/lib/rules/camelcase'; import * as util from '../util'; +import { + InferOptionsTypeFromRule, + InferMessageIdsTypeFromRule +} from '../tsestree-utils'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -interface Options { - ignoreDestructuring?: boolean; - properties?: 'always' | 'never'; - allow?: string[]; -} +type Options = InferOptionsTypeFromRule; +type MessageIds = InferMessageIdsTypeFromRule; -const defaultOptions: [Required] = [ +const defaultOptions: Options = [ { allow: ['^UNSAFE_'], ignoreDestructuring: false, @@ -25,7 +26,7 @@ const defaultOptions: [Required] = [ } ]; -const rule: RuleModule<'notCamelCase', [Options]> = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { @@ -49,7 +50,7 @@ const rule: RuleModule<'notCamelCase', [Options]> = { const options = util.applyDefault(defaultOptions, context.options)[0]; const properties = options.properties; - const allow = options.allow; + const allow = options.allow!; /** * Checks if a string contains an underscore and isn't all upper-case diff --git a/packages/eslint-plugin/src/rules/indent.ts b/packages/eslint-plugin/src/rules/indent.ts index ffd2665127fd..72643c69f928 100644 --- a/packages/eslint-plugin/src/rules/indent.ts +++ b/packages/eslint-plugin/src/rules/indent.ts @@ -1,15 +1,26 @@ /** * @fileoverview Rule to flag non-camelcased identifiers - * @author Patricio Trevino + * + * Note this file is rather type-unsafe in its current state. + * This is due to some really funky type conversions between different node types. + * This is done intentionally based on the internal implementation of the base indent rule. */ -import RuleModule from 'ts-eslint'; +import { TSESTree } from '@typescript-eslint/typescript-estree'; import baseRule from 'eslint/lib/rules/indent'; +import RuleModule from 'ts-eslint'; import * as util from '../util'; +import { + InferOptionsTypeFromRule, + InferMessageIdsTypeFromRule +} from '../tsestree-utils'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ +type Options = InferOptionsTypeFromRule; +type MessageIds = InferMessageIdsTypeFromRule; +type Range = [number, number]; const KNOWN_NODES = new Set([ // Class properties aren't yet supported by eslint... @@ -78,7 +89,7 @@ const KNOWN_NODES = new Set([ 'TSUnionType' ]); -const defaultOptions = [ +const defaultOptions: Options = [ // typescript docs and playground use 4 space indent 4, { @@ -90,7 +101,7 @@ const defaultOptions = [ } ]; -const rule: Rule.RuleModule = Object.assign({}, baseRule, { +const rule: RuleModule = { meta: { type: 'layout', docs: { @@ -108,7 +119,7 @@ const rule: Rule.RuleModule = Object.assign({}, baseRule, { create(context) { // because we extend the base rule, have to update opts on the context // the context defines options as readonly though... - const contextWithDefaults: Rule.RuleContext = Object.create(context, { + const contextWithDefaults: typeof context = Object.create(context, { options: { writable: false, configurable: false, @@ -120,15 +131,21 @@ const rule: Rule.RuleModule = Object.assign({}, baseRule, { /** * Converts from a TSPropertySignature to a Property - * @param {ASTNode} node a TSPropertySignature node + * @param node a TSPropertySignature node * @param [type] the type to give the new node - * @returns {Object} a Property node + * @returns a Property node */ - function TSPropertySignatureToProperty(node, type: string = 'Property') { - return { - type, - key: node.key, - value: node.value || node.typeAnnotation, + function TSPropertySignatureToProperty( + node: + | TSESTree.TSPropertySignature + | TSESTree.TSEnumMember + | TSESTree.TypeElement, + type: 'ClassProperty' | 'Property' = 'Property' + ): TSESTree.Node | null { + const base = { + // indent doesn't actually use these + key: null as any, + value: null as any, // Property flags computed: false, @@ -142,25 +159,38 @@ const rule: Rule.RuleModule = Object.assign({}, baseRule, { range: node.range, loc: node.loc }; + if (type === 'Property') { + return { + type, + ...base + } as TSESTree.Property; + } else { + return { + type, + static: false, + readonly: false, + ...base + } as TSESTree.ClassProperty; + } } return Object.assign({}, rules, { // overwrite the base rule here so we can use our KNOWN_NODES list instead - '*:exit'(node) { + '*:exit'(node: TSESTree.Node) { // For nodes we care about, skip the default handling, because it just marks the node as ignored... if (!KNOWN_NODES.has(node.type)) { rules['*:exit'](node); } }, - TSAsExpression(node) { + TSAsExpression(node: TSESTree.TSAsExpression) { // transform it to a BinaryExpression return rules['BinaryExpression, LogicalExpression']({ type: 'BinaryExpression', operator: 'as', left: node.expression, // the first typeAnnotation includes the as token - right: node.typeAnnotation, + right: node.typeAnnotation as any, // location data parent: node.parent, @@ -169,15 +199,15 @@ const rule: Rule.RuleModule = Object.assign({}, baseRule, { }); }, - TSConditionalType(node) { + TSConditionalType(node: TSESTree.TSConditionalType) { // transform it to a ConditionalExpression return rules.ConditionalExpression({ type: 'ConditionalExpression', test: { - type: 'BinaryExpression', + type: 'BinaryExpression' as 'BinaryExpression', operator: 'extends', - left: node.checkType, - right: node.extendsType, + left: node.checkType as any, + right: node.extendsType as any, // location data range: [node.checkType.range[0], node.extendsType.range[1]], @@ -186,8 +216,8 @@ const rule: Rule.RuleModule = Object.assign({}, baseRule, { end: node.extendsType.loc.end } }, - consequent: node.trueType, - alternate: node.falseType, + consequent: node.trueType as any, + alternate: node.falseType as any, // location data parent: node.parent, @@ -196,12 +226,16 @@ const rule: Rule.RuleModule = Object.assign({}, baseRule, { }); }, - 'TSEnumDeclaration, TSTypeLiteral'(node) { + 'TSEnumDeclaration, TSTypeLiteral'( + node: TSESTree.TSEnumDeclaration | TSESTree.TSTypeLiteral + ) { // transform it to an ObjectExpression return rules['ObjectExpression, ObjectPattern']({ type: 'ObjectExpression', - properties: node.members.map(member => - TSPropertySignatureToProperty(member) + properties: (node.members as ( + | TSESTree.TSEnumMember + | TSESTree.TypeElement)[]).map( + member => TSPropertySignatureToProperty(member) as TSESTree.Property ), // location data @@ -211,40 +245,44 @@ const rule: Rule.RuleModule = Object.assign({}, baseRule, { }); }, - TSImportEqualsDeclaration(node) { + TSImportEqualsDeclaration(node: TSESTree.TSImportEqualsDeclaration) { // transform it to an VariableDeclaration // use VariableDeclaration instead of ImportDeclaration because it's essentially the same thing const { id, moduleReference } = node; return rules.VariableDeclaration({ type: 'VariableDeclaration', + kind: 'const' as 'const', declarations: [ { - type: 'VariableDeclarator', - range: [id.range[0], moduleReference.range[1]], + type: 'VariableDeclarator' as 'VariableDeclarator', + range: [id.range[0], moduleReference.range[1]] as Range, loc: { start: id.loc.start, end: moduleReference.loc.end }, id: id, init: { - type: 'CallExpression', + type: 'CallExpression' as 'CallExpression', callee: { - type: 'Identifier', + type: 'Identifier' as 'Identifier', name: 'require', range: [ moduleReference.range[0], moduleReference.range[0] + 'require'.length - ], + ] as Range, loc: { start: moduleReference.loc.start, end: { line: moduleReference.loc.end.line, - column: moduleReference.loc.start + 'require'.length + column: moduleReference.loc.start.line + 'require'.length } } }, - arguments: [moduleReference.expression], + arguments: + 'expression' in moduleReference + ? [moduleReference.expression] + : [], // location data range: moduleReference.range, @@ -260,12 +298,12 @@ const rule: Rule.RuleModule = Object.assign({}, baseRule, { }); }, - TSIndexedAccessType(node) { + TSIndexedAccessType(node: TSESTree.TSIndexedAccessType) { // convert to a MemberExpression return rules['MemberExpression, JSXMemberExpression, MetaProperty']({ type: 'MemberExpression', - object: node.objectType, - property: node.indexType, + object: node.objectType as any, + property: node.indexType as any, // location data parent: node.parent, @@ -274,12 +312,16 @@ const rule: Rule.RuleModule = Object.assign({}, baseRule, { }); }, - TSInterfaceBody(node) { + TSInterfaceBody(node: TSESTree.TSInterfaceBody) { // transform it to an ClassBody return rules['BlockStatement, ClassBody']({ type: 'ClassBody', - body: node.body.map(p => - TSPropertySignatureToProperty(p, 'ClassProperty') + body: node.body.map( + p => + TSPropertySignatureToProperty( + p, + 'ClassProperty' + ) as TSESTree.ClassProperty ), // location data @@ -289,15 +331,18 @@ const rule: Rule.RuleModule = Object.assign({}, baseRule, { }); }, - 'TSInterfaceDeclaration[extends.length > 0]'(node) { + 'TSInterfaceDeclaration[extends.length > 0]'( + node: TSESTree.TSInterfaceDeclaration + ) { // transform it to a ClassDeclaration return rules[ 'ClassDeclaration[superClass], ClassExpression[superClass]' ]({ type: 'ClassDeclaration', - body: node.body, + body: node.body as any, + id: undefined, // TODO: This is invalid, there can be more than one extends in interface - superClass: node.extends[0].expression, + superClass: node.extends![0].expression as any, // location data parent: node.parent, @@ -306,30 +351,38 @@ const rule: Rule.RuleModule = Object.assign({}, baseRule, { }); }, - TSMappedType(node) { + TSMappedType(node: TSESTree.TSMappedType) { const sourceCode = context.getSourceCode(); const squareBracketStart = sourceCode.getTokenBefore( node.typeParameter - ); + )!; // transform it to an ObjectExpression return rules['ObjectExpression, ObjectPattern']({ type: 'ObjectExpression', properties: [ { - type: 'Property', - key: node.typeParameter, - value: node.typeAnnotation, + type: 'Property' as 'Property', + key: node.typeParameter as any, + value: node.typeAnnotation as any, // location data range: [ squareBracketStart.range[0], - node.typeAnnotation.range[1] - ], + node.typeAnnotation + ? node.typeAnnotation.range[1] + : squareBracketStart.range[0] + ] as Range, loc: { start: squareBracketStart.loc.start, - end: node.typeAnnotation.loc.end - } + end: node.typeAnnotation + ? node.typeAnnotation.loc.end + : squareBracketStart.loc.end + }, + kind: 'init' as 'init', + computed: false, + method: false, + shorthand: false } ], @@ -340,7 +393,7 @@ const rule: Rule.RuleModule = Object.assign({}, baseRule, { }); }, - TSModuleBlock(node) { + TSModuleBlock(node: TSESTree.TSModuleBlock) { // transform it to a BlockStatement return rules['BlockStatement, ClassBody']({ type: 'BlockStatement', @@ -353,11 +406,11 @@ const rule: Rule.RuleModule = Object.assign({}, baseRule, { }); }, - TSQualifiedName(node) { + TSQualifiedName(node: TSESTree.TSQualifiedName) { return rules['MemberExpression, JSXMemberExpression, MetaProperty']({ type: 'MemberExpression', - object: node.left, - property: node.right, + object: node.left as any, + property: node.right as any, // location data parent: node.parent, @@ -366,11 +419,11 @@ const rule: Rule.RuleModule = Object.assign({}, baseRule, { }); }, - TSTupleType(node) { + TSTupleType(node: TSESTree.TSTupleType) { // transform it to an ArrayExpression return rules['ArrayExpression, ArrayPattern']({ type: 'ArrayExpression', - elements: node.elementTypes, + elements: node.elementTypes as any, // location data parent: node.parent, @@ -379,7 +432,7 @@ const rule: Rule.RuleModule = Object.assign({}, baseRule, { }); }, - TSTypeParameterDeclaration(node) { + TSTypeParameterDeclaration(node: TSESTree.TSTypeParameterDeclaration) { const [name, ...attributes] = node.params; // JSX is about the closest we can get because the angle brackets @@ -387,8 +440,8 @@ const rule: Rule.RuleModule = Object.assign({}, baseRule, { return rules.JSXOpeningElement({ type: 'JSXOpeningElement', selfClosing: false, - name, - attributes, + name: name as any, + attributes: attributes as any, // location data parent: node.parent, @@ -398,5 +451,5 @@ const rule: Rule.RuleModule = Object.assign({}, baseRule, { } }); } -}); +}; export = rule; diff --git a/packages/eslint-plugin/src/tsestree-utils.ts b/packages/eslint-plugin/src/tsestree-utils.ts index 92cbd839611d..badf63597385 100644 --- a/packages/eslint-plugin/src/tsestree-utils.ts +++ b/packages/eslint-plugin/src/tsestree-utils.ts @@ -3,6 +3,7 @@ */ import { TSESTree } from '@typescript-eslint/typescript-estree'; +import RuleModule from 'ts-eslint'; export function getNameFromPropertyName( propertyName: TSESTree.PropertyName @@ -12,3 +13,17 @@ export function getNameFromPropertyName( } return propertyName.value; } + +export type InferOptionsTypeFromRule = T extends RuleModule< + any, + infer TOptions +> + ? TOptions + : unknown; + +export type InferMessageIdsTypeFromRule = T extends RuleModule< + infer TMessageIds, + any +> + ? TMessageIds + : unknown; diff --git a/packages/eslint-plugin/tests/RuleTester.ts b/packages/eslint-plugin/tests/RuleTester.ts index de87f7acb338..1027b710ca00 100644 --- a/packages/eslint-plugin/tests/RuleTester.ts +++ b/packages/eslint-plugin/tests/RuleTester.ts @@ -27,10 +27,7 @@ interface TestCaseError { // endColumn?: number; } -interface RuleTesterRunTests< - TMessageIds extends string, - TOptions extends any[] -> { +interface RunTests { // RuleTester.run also accepts strings for valid cases valid: (ValidTestCase | string)[]; invalid: InvalidTestCase[]; @@ -40,7 +37,7 @@ declare class RuleTesterTyped { run( name: string, rule: RuleModule, - tests: RuleTesterRunTests + tests: RunTests ): void; } @@ -48,3 +45,4 @@ const RuleTesterRetyped = (RuleTester as any) as { new (config?: any): RuleTesterTyped; }; export default RuleTesterRetyped; +export { RunTests, TestCaseError }; diff --git a/packages/eslint-plugin/tests/rules/indent.test.ts b/packages/eslint-plugin/tests/rules/indent.test.ts index 714d8e5bf7c7..07234f7526bf 100644 --- a/packages/eslint-plugin/tests/rules/indent.test.ts +++ b/packages/eslint-plugin/tests/rules/indent.test.ts @@ -9,7 +9,14 @@ //------------------------------------------------------------------------------ import rule from '../../src/rules/indent'; -import { RuleTester, RuleTesterRunTests } from 'eslint'; +import RuleTester, { RunTests, TestCaseError } from '../RuleTester'; +import { + InferOptionsTypeFromRule, + InferMessageIdsTypeFromRule +} from '../../src/tsestree-utils'; + +type Options = InferOptionsTypeFromRule; +type MessageIds = InferMessageIdsTypeFromRule; /** * Marks a test case as a plain javascript case which should be indented the same @@ -611,7 +618,7 @@ type Foo = string | { ` ] } -].reduce( +].reduce>( (acc, testCase) => { const indent = ' '; @@ -633,7 +640,7 @@ type Foo = string | { output: code, errors: code .split('\n') - .map((line, lineNum) => { + .map | null>((line, lineNum) => { const indentCount = line.split(indent).length - 1; const spaceCount = indentCount * indent.length; @@ -642,12 +649,16 @@ type Foo = string | { } return { - message: `Expected indentation of ${spaceCount} spaces but found 0.`, + messageId: 'wrongIndentation', + data: { + expected: `${spaceCount} spaces`, + actual: 0 + }, line: lineNum + 1, column: 1 }; }) - .filter((error): error is RuleTester.TestCaseError => error !== null) + .filter((error): error is TestCaseError => error !== null) }); }); @@ -757,12 +768,20 @@ type Foo = { `, errors: [ { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 3, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 4, column: 1 } @@ -799,52 +818,92 @@ interface Foo { `, errors: [ { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 3, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 4, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 5, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 6, column: 1 }, { - message: `Expected indentation of 8 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '8 spaces', + actual: 0 + }, line: 7, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 8, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 9, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 10, column: 1 }, { - message: `Expected indentation of 8 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '8 spaces', + actual: 0 + }, line: 11, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 12, column: 1 } @@ -869,22 +928,38 @@ interface Foo { `, errors: [ { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 3, column: 1 }, { - message: `Expected indentation of 8 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '8 spaces', + actual: 0 + }, line: 4, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 5, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 6, column: 1 } @@ -905,12 +980,20 @@ interface Foo extends Bar { `, errors: [ { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 3, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 4, column: 1 } @@ -935,17 +1018,29 @@ class Foo `, errors: [ { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 3, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 4, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 5, column: 1 } @@ -968,17 +1063,29 @@ interface Foo `, errors: [ { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 3, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 4, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 5, column: 1 } @@ -999,12 +1106,20 @@ const foo : Foo<{ `, errors: [ { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 3, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 4, column: 1 } @@ -1031,22 +1146,38 @@ type T = { `, errors: [ { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 3, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 4, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 6, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 7, column: 1 } @@ -1077,32 +1208,56 @@ type T = `, errors: [ { - message: `Expected indentation of 8 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '8 spaces', + actual: 0 + }, line: 4, column: 1 }, { - message: `Expected indentation of 8 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '8 spaces', + actual: 0 + }, line: 5, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 6, column: 1 }, { - message: `Expected indentation of 8 spaces but found 4.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '8 spaces', + actual: 4 + }, line: 8, column: 1 }, { - message: `Expected indentation of 8 spaces but found 4.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '8 spaces', + actual: 4 + }, line: 9, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 10, column: 1 } @@ -1117,7 +1272,11 @@ import Dialogs = require("widgets/Dialogs"); `, errors: [ { - message: `Expected indentation of 0 spaces but found 4.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '0 spaces', + actual: 4 + }, line: 2, column: 1 } @@ -1158,62 +1317,110 @@ class Foo { `, errors: [ { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 3, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 4, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 5, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 6, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 7, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 8, column: 1 }, { - message: `Expected indentation of 8 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '8 spaces', + actual: 0 + }, line: 9, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 10, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 11, column: 1 }, { - message: `Expected indentation of 8 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '8 spaces', + actual: 0 + }, line: 12, column: 1 }, { - message: `Expected indentation of 8 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '8 spaces', + actual: 0 + }, line: 13, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 14, column: 1 } @@ -1230,12 +1437,20 @@ class Foo {} `, errors: [ { - message: `Expected indentation of 0 spaces but found 4.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '0 spaces', + actual: 4 + }, line: 2, column: 1 }, { - message: `Expected indentation of 0 spaces but found 4.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '0 spaces', + actual: 4 + }, line: 3, column: 1 } @@ -1258,17 +1473,29 @@ enum Foo { `, errors: [ { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 3, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 4, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 5, column: 1 } @@ -1291,17 +1518,29 @@ const enum Foo { `, errors: [ { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 3, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 4, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 5, column: 1 } @@ -1316,7 +1555,11 @@ export = Foo; `, errors: [ { - message: `Expected indentation of 0 spaces but found 4.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '0 spaces', + actual: 4 + }, line: 2, column: 1 } @@ -1331,7 +1574,11 @@ declare function h(x: number): number; `, errors: [ { - message: `Expected indentation of 0 spaces but found 4.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '0 spaces', + actual: 4 + }, line: 2, column: 1 } @@ -1350,7 +1597,11 @@ declare function h( `, errors: [ { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 3, column: 1 } @@ -1373,17 +1624,29 @@ namespace Validation { `, errors: [ { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 3, column: 1 }, { - message: `Expected indentation of 8 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '8 spaces', + actual: 0 + }, line: 4, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 5, column: 1 } @@ -1406,17 +1669,29 @@ declare module "Validation" { `, errors: [ { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 3, column: 1 }, { - message: `Expected indentation of 8 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '8 spaces', + actual: 0 + }, line: 4, column: 1 }, { - message: `Expected indentation of 4 spaces but found 0.`, + messageId: 'wrongIndentation' as 'wrongIndentation', + data: { + expected: '4 spaces', + actual: 0 + }, line: 5, column: 1 } diff --git a/packages/eslint-plugin/typings/eslint-rules.d.ts b/packages/eslint-plugin/typings/eslint-rules.d.ts index ca45537c0a3c..7b5cded3d951 100644 --- a/packages/eslint-plugin/typings/eslint-rules.d.ts +++ b/packages/eslint-plugin/typings/eslint-rules.d.ts @@ -13,13 +13,111 @@ declare module 'eslint/lib/rules/camelcase' { 'notCamelCase', [ { + allow?: string[]; ignoreDestructuring?: boolean; properties?: 'always' | 'never'; - allow?: string[]; } ], { - Identifier: (node: TSESTree.Node) => void; + Identifier(node: TSESTree.Identifier): void; + } + >; + export = rule; +} + +declare module 'eslint/lib/rules/indent' { + import { TSESTree } from '@typescript-eslint/typescript-estree'; + import RuleModule from 'ts-eslint'; + + type Listener = (node: TSESTree.Node) => void; + type ElementList = number | 'first' | 'off'; + const rule: RuleModule< + 'wrongIndentation', + [ + 'tab' | number, + { + SwitchCase?: number; + VariableDeclarator?: + | ElementList + | { + var?: ElementList; + let?: ElementList; + const?: ElementList; + }; + outerIIFEBody?: number; + MemberExpression?: number | 'off'; + FunctionDeclaration?: { + parameters?: ElementList; + body?: number; + }; + FunctionExpression?: { + parameters?: ElementList; + body?: number; + }; + CallExpression?: { + arguments?: ElementList; + }; + ArrayExpression?: ElementList; + ObjectExpression?: ElementList; + ImportDeclaration?: ElementList; + flatTernaryExpressions?: boolean; + ignoredNodes?: string[]; + ignoreComments?: boolean; + } + ], + { + '*:exit'(node: TSESTree.Node): void; + 'ArrayExpression, ArrayPattern'( + node: TSESTree.ArrayExpression | TSESTree.ArrayPattern + ): void; + 'ObjectExpression, ObjectPattern'( + node: TSESTree.ObjectExpression | TSESTree.ObjectPattern + ): void; + ArrowFunctionExpression(node: TSESTree.ArrowFunctionExpression): void; + AssignmentExpression(node: TSESTree.AssignmentExpression): void; + 'BinaryExpression, LogicalExpression'( + node: TSESTree.BinaryExpression | TSESTree.LogicalExpression + ): void; + 'BlockStatement, ClassBody'( + node: TSESTree.BlockStatement | TSESTree.ClassBody + ): void; + CallExpression(node: TSESTree.CallExpression): void; + 'ClassDeclaration[superClass], ClassExpression[superClass]'( + node: TSESTree.ClassDeclaration | TSESTree.ClassExpression + ): void; + ConditionalExpression(node: TSESTree.ConditionalExpression): void; + 'DoWhileStatement, WhileStatement, ForInStatement, ForOfStatement'( + node: + | TSESTree.DoWhileStatement + | TSESTree.WhileStatement + | TSESTree.ForInStatement + | TSESTree.ForOfStatement + ): void; + ExportNamedDeclaration(node: TSESTree.ExportNamedDeclaration): void; + ForStatement(node: TSESTree.ForStatement): void; + 'FunctionDeclaration, FunctionExpression'( + node: TSESTree.FunctionDeclaration | TSESTree.FunctionExpression + ): void; + IfStatement(node: TSESTree.IfStatement): void; + ImportDeclaration(node: TSESTree.ImportDeclaration): void; + 'MemberExpression, JSXMemberExpression, MetaProperty'( + node: + | TSESTree.MemberExpression + | TSESTree.JSXMemberExpression + | TSESTree.MetaProperty + ): void; + NewExpression(node: TSESTree.NewExpression): void; + Property(node: TSESTree.Property): void; + SwitchStatement(node: TSESTree.SwitchStatement): void; + SwitchCase(node: TSESTree.SwitchCase): void; + TemplateLiteral(node: TSESTree.TemplateLiteral): void; + VariableDeclaration(node: TSESTree.VariableDeclaration): void; + VariableDeclarator(node: TSESTree.VariableDeclarator): void; + 'JSXAttribute[value]'(node: TSESTree.JSXAttribute): void; + JSXElement(node: TSESTree.JSXElement): void; + JSXOpeningElement(node: TSESTree.JSXOpeningElement): void; + JSXClosingElement(node: TSESTree.JSXClosingElement): void; + JSXExpressionContainer(node: TSESTree.JSXExpressionContainer): void; } >; export = rule; diff --git a/packages/typescript-estree/src/typedefs.ts b/packages/typescript-estree/src/typedefs.ts index ef8ba3966da7..3bbd1f3197c2 100644 --- a/packages/typescript-estree/src/typedefs.ts +++ b/packages/typescript-estree/src/typedefs.ts @@ -277,10 +277,7 @@ export type JSXExpression = | JSXEmptyExpression | JSXSpreadChild | JSXExpressionContainer; -export type JSXTagNameExpression = - | Identifier - | MemberExpression - | ThisExpression; +export type JSXTagNameExpression = JSXIdentifier | JSXMemberExpression; export type LeftHandSideExpression = | CallExpression | ClassExpression @@ -412,12 +409,12 @@ interface BinaryExpressionBase extends NodeBase { } interface ClassDeclarationBase extends NodeBase { - typeParameters: TSTypeParameterDeclaration; - superTypeParameters: TSTypeParameterInstantiation; - id: Identifier | undefined; + typeParameters?: TSTypeParameterDeclaration; + superTypeParameters?: TSTypeParameterInstantiation; + id?: Identifier; body: ClassBody; - superClass: LeftHandSideExpression | undefined; - implements: ExpressionWithTypeArguments[]; + superClass?: LeftHandSideExpression; + implements?: ExpressionWithTypeArguments[]; abstract?: boolean; declare?: boolean; decorators?: Decorator[]; @@ -428,7 +425,7 @@ interface ClassPropertyBase extends NodeBase { value: Expression; computed: boolean; static: boolean; - readonly: boolean | undefined; + readonly?: boolean; decorators?: Decorator[]; accessibility?: Accessibility; optional?: boolean; @@ -442,7 +439,7 @@ interface FunctionDeclarationBase extends NodeBase { expression: boolean; async: boolean; params: Parameter[]; - body: BlockStatement | null | undefined; + body?: BlockStatement | null; returnType?: TSTypeAnnotation; typeParameters?: TSTypeParameterDeclaration; } @@ -751,9 +748,14 @@ export interface JSXIdentifier extends NodeBase { name: string; } +export interface JSXMemberExpression extends NodeBase { + type: 'JSXMemberExpression'; + name: string; +} + export interface JSXOpeningElement extends NodeBase { type: 'JSXOpeningElement'; - typeParameters: TSTypeParameterInstantiation | undefined; + typeParameters?: TSTypeParameterInstantiation; selfClosing: boolean; name: JSXTagNameExpression; attributes: JSXAttribute[]; @@ -994,8 +996,8 @@ export interface TSDeclareFunction extends NodeBase { generator: boolean; expression: boolean; async: boolean; - params: Parameter; - body: BlockStatement | null | undefined; + params: Parameter[]; + body?: BlockStatement | null; returnType?: TSTypeAnnotation; declare: boolean; typeParameters?: TSTypeParameterDeclaration; @@ -1066,7 +1068,7 @@ export interface TSIndexedAccessType extends NodeBase { export interface TSIndexSignature extends NodeBase { type: 'TSIndexSignature'; - parameters: Parameter; + parameters: Parameter[]; typeAnnotation?: TSTypeAnnotation; readonly?: boolean; accessibility?: Accessibility; @@ -1177,10 +1179,10 @@ export interface TSOptionalType extends NodeBase { export interface TSParameterProperty extends NodeBase { type: 'TSParameterProperty'; - accessibility: Accessibility | undefined; - readonly: boolean | undefined; - static: boolean | undefined; - export: boolean | undefined; + accessibility?: Accessibility; + readonly?: boolean; + static?: boolean; + export?: boolean; parameter: AssignmentPattern | BindingName | RestElement; } @@ -1191,14 +1193,14 @@ export interface TSParenthesizedType extends NodeBase { export interface TSPropertySignature extends NodeBase { type: 'TSPropertySignature'; - optional: boolean | undefined; + optional?: boolean; computed: boolean; key: PropertyName; - typeAnnotation: TSTypeAnnotation | undefined; - initializer: Expression | undefined; - readonly: boolean | undefined; - static: boolean | undefined; - export: boolean | undefined; + typeAnnotation?: TSTypeAnnotation; + initializer?: Expression; + readonly?: boolean; + static?: boolean; + export?: boolean; accessability?: Accessibility; } @@ -1283,8 +1285,8 @@ export interface TSTypeOperator extends NodeBase { export interface TSTypeParameter extends NodeBase { type: 'TSTypeParameter'; name: Identifier; - constraint: TypeNode | undefined; - default: TypeNode | undefined; + constraint?: TypeNode; + default?: TypeNode; } export interface TSTypeParameterDeclaration extends NodeBase { @@ -1311,7 +1313,7 @@ export interface TSTypeQuery extends NodeBase { export interface TSTypeReference extends NodeBase { type: 'TSTypeReference'; typeName: EntityName; - typeParameters: TSTypeParameterInstantiation | undefined; + typeParameters?: TSTypeParameterInstantiation; } export interface TSUndefinedKeyword extends NodeBase { diff --git a/yarn.lock b/yarn.lock index 180a9f89f8bf..c3cfb2d8feec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2409,49 +2409,6 @@ eslint@^5.12.1: table "^5.0.2" text-table "^0.2.0" -eslint@^5.9.0: - version "5.12.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.12.0.tgz#fab3b908f60c52671fb14e996a450b96c743c859" - integrity sha512-LntwyPxtOHrsJdcSwyQKVtHofPHdv+4+mFwEe91r2V13vqpM8yLr7b1sW+Oo/yheOPkWYsYlYJCkzlFAt8KV7g== - dependencies: - "@babel/code-frame" "^7.0.0" - ajv "^6.5.3" - chalk "^2.1.0" - cross-spawn "^6.0.5" - debug "^4.0.1" - doctrine "^2.1.0" - eslint-scope "^4.0.0" - eslint-utils "^1.3.1" - eslint-visitor-keys "^1.0.0" - espree "^5.0.0" - esquery "^1.0.1" - esutils "^2.0.2" - file-entry-cache "^2.0.0" - functional-red-black-tree "^1.0.1" - glob "^7.1.2" - globals "^11.7.0" - ignore "^4.0.6" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - inquirer "^6.1.0" - js-yaml "^3.12.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" - lodash "^4.17.5" - minimatch "^3.0.4" - mkdirp "^0.5.1" - natural-compare "^1.4.0" - optionator "^0.8.2" - path-is-inside "^1.0.2" - pluralize "^7.0.0" - progress "^2.0.0" - regexpp "^2.0.1" - semver "^5.5.1" - strip-ansi "^4.0.0" - strip-json-comments "^2.0.1" - table "^5.0.2" - text-table "^0.2.0" - espree@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.0.tgz#fc7f984b62b36a0f543b13fb9cd7b9f4a7f5b65c" From 0f9b863be4dcb2085c656b7f6f7897f701bd364c Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Thu, 31 Jan 2019 21:51:49 -0800 Subject: [PATCH 35/92] add comment to ts-estree types --- packages/eslint-plugin/src/util.ts | 10 ++--- packages/eslint-plugin/typings/ts-eslint.d.ts | 45 ++++++++++--------- packages/typescript-estree/src/typedefs.ts | 5 +++ 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/packages/eslint-plugin/src/util.ts b/packages/eslint-plugin/src/util.ts index d83ee6222021..3c4510ffc81d 100644 --- a/packages/eslint-plugin/src/util.ts +++ b/packages/eslint-plugin/src/util.ts @@ -1,6 +1,5 @@ import { ParserServices } from '@typescript-eslint/parser'; - -import { RuleContext } from './RuleModule'; +import { RuleContext } from 'ts-eslint'; // note - cannot migrate this to an import statement because it will make TSC copy the package.json to the dist folder const version = require('../package.json').version; @@ -127,9 +126,10 @@ export function upperCaseFirst(str: string) { /** * Try to retrieve typescript parser service from context */ -export function getParserServices( - context: RuleContext -): ParserServices { +export function getParserServices< + TMessageIds extends string, + TOptions extends any[] +>(context: RuleContext): ParserServices { if ( !context.parserServices || !context.parserServices.program || diff --git a/packages/eslint-plugin/typings/ts-eslint.d.ts b/packages/eslint-plugin/typings/ts-eslint.d.ts index 065342941ae2..51f6a91380c7 100644 --- a/packages/eslint-plugin/typings/ts-eslint.d.ts +++ b/packages/eslint-plugin/typings/ts-eslint.d.ts @@ -11,7 +11,6 @@ declare module 'ts-eslint' { import { TSESTree } from '@typescript-eslint/typescript-estree'; import { ParserServices } from '@typescript-eslint/parser'; import { AST, Linter, Scope } from 'eslint'; - import { Comment as ESTreeComment } from 'estree'; import { JSONSchema4 } from 'json-schema'; //#region SourceCode @@ -31,7 +30,7 @@ declare module 'ts-eslint' { } export type FilterPredicate = ( - tokenOrComment: AST.Token | ESTreeComment + tokenOrComment: AST.Token | TSESTree.Comment ) => boolean; export type CursorWithSkipOptions = @@ -77,11 +76,11 @@ declare module 'ts-eslint' { getLines(): string[]; - getAllComments(): ESTreeComment[]; + getAllComments(): TSESTree.Comment[]; getComments( node: TSESTree.Node - ): { leading: ESTreeComment[]; trailing: ESTreeComment[] }; + ): { leading: TSESTree.Comment[]; trailing: TSESTree.Comment[] }; getJSDocComment(node: TSESTree.Node): AST.Token | null; @@ -122,52 +121,52 @@ declare module 'ts-eslint' { ): AST.Token[]; getTokenBefore( - node: TSESTree.Node | AST.Token | ESTreeComment, + node: TSESTree.Node | AST.Token | TSESTree.Comment, options?: SourceCode.CursorWithSkipOptions ): AST.Token | null; getTokensBefore( - node: TSESTree.Node | AST.Token | ESTreeComment, + node: TSESTree.Node | AST.Token | TSESTree.Comment, options?: SourceCode.CursorWithCountOptions ): AST.Token[]; getTokenAfter( - node: TSESTree.Node | AST.Token | ESTreeComment, + node: TSESTree.Node | AST.Token | TSESTree.Comment, options?: SourceCode.CursorWithSkipOptions ): AST.Token | null; getTokensAfter( - node: TSESTree.Node | AST.Token | ESTreeComment, + node: TSESTree.Node | AST.Token | TSESTree.Comment, options?: SourceCode.CursorWithCountOptions ): AST.Token[]; getFirstTokenBetween( - left: TSESTree.Node | AST.Token | ESTreeComment, - right: TSESTree.Node | AST.Token | ESTreeComment, + left: TSESTree.Node | AST.Token | TSESTree.Comment, + right: TSESTree.Node | AST.Token | TSESTree.Comment, options?: SourceCode.CursorWithSkipOptions ): AST.Token | null; getFirstTokensBetween( - left: TSESTree.Node | AST.Token | ESTreeComment, - right: TSESTree.Node | AST.Token | ESTreeComment, + left: TSESTree.Node | AST.Token | TSESTree.Comment, + right: TSESTree.Node | AST.Token | TSESTree.Comment, options?: SourceCode.CursorWithCountOptions ): AST.Token[]; getLastTokenBetween( - left: TSESTree.Node | AST.Token | ESTreeComment, - right: TSESTree.Node | AST.Token | ESTreeComment, + left: TSESTree.Node | AST.Token | TSESTree.Comment, + right: TSESTree.Node | AST.Token | TSESTree.Comment, options?: SourceCode.CursorWithSkipOptions ): AST.Token | null; getLastTokensBetween( - left: TSESTree.Node | AST.Token | ESTreeComment, - right: TSESTree.Node | AST.Token | ESTreeComment, + left: TSESTree.Node | AST.Token | TSESTree.Comment, + right: TSESTree.Node | AST.Token | TSESTree.Comment, options?: SourceCode.CursorWithCountOptions ): AST.Token[]; getTokensBetween( - left: TSESTree.Node | AST.Token | ESTreeComment, - right: TSESTree.Node | AST.Token | ESTreeComment, + left: TSESTree.Node | AST.Token | TSESTree.Comment, + right: TSESTree.Node | AST.Token | TSESTree.Comment, padding?: | number | SourceCode.FilterPredicate @@ -190,11 +189,15 @@ declare module 'ts-eslint' { right: TSESTree.Node | AST.Token ): boolean; - getCommentsBefore(nodeOrToken: TSESTree.Node | AST.Token): ESTreeComment[]; + getCommentsBefore( + nodeOrToken: TSESTree.Node | AST.Token + ): TSESTree.Comment[]; - getCommentsAfter(nodeOrToken: TSESTree.Node | AST.Token): ESTreeComment[]; + getCommentsAfter( + nodeOrToken: TSESTree.Node | AST.Token + ): TSESTree.Comment[]; - getCommentsInside(node: TSESTree.Node): ESTreeComment[]; + getCommentsInside(node: TSESTree.Node): TSESTree.Comment[]; } //#endregion SourceCode diff --git a/packages/typescript-estree/src/typedefs.ts b/packages/typescript-estree/src/typedefs.ts index 3bbd1f3197c2..a84acda142dd 100644 --- a/packages/typescript-estree/src/typedefs.ts +++ b/packages/typescript-estree/src/typedefs.ts @@ -575,6 +575,11 @@ export interface ClassProperty extends ClassPropertyBase { type: 'ClassProperty'; } +export interface Comment extends NodeBase { + type: 'Line' | 'Block'; + value: string; +} + export interface ConditionalExpression extends NodeBase { type: 'ConditionalExpression'; test: Expression; From f35c261904e7ccf1391c9a48e6cf80020c65abfc Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Thu, 31 Jan 2019 21:56:12 -0800 Subject: [PATCH 36/92] switch from npmignore to package.json files --- packages/eslint-plugin/.npmignore | 5 ----- packages/eslint-plugin/package.json | 7 +++++++ 2 files changed, 7 insertions(+), 5 deletions(-) delete mode 100644 packages/eslint-plugin/.npmignore diff --git a/packages/eslint-plugin/.npmignore b/packages/eslint-plugin/.npmignore deleted file mode 100644 index d684bcadbd2d..000000000000 --- a/packages/eslint-plugin/.npmignore +++ /dev/null @@ -1,5 +0,0 @@ -**/* -!dist/**/* -!docs/**/* -!package.json -!README.md diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 9042e5c1fde3..ee16a90aa80c 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -11,6 +11,13 @@ "engines": { "node": ">=6" }, + "files": [ + "dist", + "docs", + "package.json", + "README.md", + "LICENSE" + ], "repository": "typescript-eslint/typescript-eslint", "bugs": { "url": "https://github.com/typescript-eslint/typescript-eslint/issues" From c49d7e85f66d63d91aae1602db7a75175623d27c Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Fri, 1 Feb 2019 09:07:01 -0800 Subject: [PATCH 37/92] interface-name-prefix --- .../src/rules/interface-name-prefix.ts | 17 +++++++++++------ .../tests/rules/interface-name-prefix.test.ts | 10 +++++----- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/packages/eslint-plugin/src/rules/interface-name-prefix.ts b/packages/eslint-plugin/src/rules/interface-name-prefix.ts index ef23f1f027b3..54a89ff05c01 100644 --- a/packages/eslint-plugin/src/rules/interface-name-prefix.ts +++ b/packages/eslint-plugin/src/rules/interface-name-prefix.ts @@ -3,25 +3,30 @@ * @author Danny Fritz */ +import { TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ +type Options = ['never' | 'always']; -const defaultOptions = ['never']; +const defaultOptions: Options = ['never']; -const rule: RuleModule = { +const rule: RuleModule<'noPrefix', Options> = { meta: { type: 'suggestion', docs: { description: 'Require that interface names be prefixed with `I`', extraDescription: [util.tslintRule('interface-name')], - category: 'TypeScript', + category: 'Stylistic Issues', url: util.metaDocsUrl('interface-name-prefix'), recommended: 'error' }, + messages: { + noPrefix: 'Interface name must not be prefixed with "I".' + }, schema: [ { enum: ['never', 'always'] @@ -53,19 +58,19 @@ const rule: RuleModule = { // Public //---------------------------------------------------------------------- return { - TSInterfaceDeclaration(node): void { + TSInterfaceDeclaration(node: TSESTree.TSInterfaceDeclaration): void { if (never) { if (isPrefixedWithI(node.id.name)) { context.report({ node: node.id, - message: 'Interface name must not be prefixed with "I".' + messageId: 'noPrefix' }); } } else { if (!isPrefixedWithI(node.id.name)) { context.report({ node: node.id, - message: 'Interface name must be prefixed with "I".' + messageId: 'noPrefix' }); } } diff --git a/packages/eslint-plugin/tests/rules/interface-name-prefix.test.ts b/packages/eslint-plugin/tests/rules/interface-name-prefix.test.ts index dbbb4214d269..77cce0b06df2 100644 --- a/packages/eslint-plugin/tests/rules/interface-name-prefix.test.ts +++ b/packages/eslint-plugin/tests/rules/interface-name-prefix.test.ts @@ -75,7 +75,7 @@ interface IAnimal { `, errors: [ { - message: 'Interface name must not be prefixed with "I".', + messageId: 'noPrefix', line: 2, column: 11 } @@ -90,7 +90,7 @@ interface Animal { options: ['always'], errors: [ { - message: 'Interface name must be prefixed with "I".', + messageId: 'noPrefix', line: 2, column: 11 } @@ -105,7 +105,7 @@ interface Iguana { options: ['always'], errors: [ { - message: 'Interface name must be prefixed with "I".', + messageId: 'noPrefix', line: 2, column: 11 } @@ -120,7 +120,7 @@ interface IIguana { options: ['never'], errors: [ { - message: 'Interface name must not be prefixed with "I".', + messageId: 'noPrefix', line: 2, column: 11 } @@ -135,7 +135,7 @@ interface IAnimal { options: ['never'], errors: [ { - message: 'Interface name must not be prefixed with "I".', + messageId: 'noPrefix', line: 2, column: 11 } From 334c9b9a910998367fda8d764ab716ded4b9ea91 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Fri, 1 Feb 2019 10:34:43 -0800 Subject: [PATCH 38/92] Switch to export default rules because it's nicer from a typescript standpoint --- package.json | 6 +++--- packages/eslint-plugin/package.json | 5 ++--- packages/eslint-plugin/src/index.ts | 12 +++++++++++- .../src/rules/adjacent-overload-signatures.ts | 8 ++++++-- packages/eslint-plugin/src/rules/array-type.ts | 16 ++++++++-------- packages/eslint-plugin/src/rules/ban-types.ts | 6 ++++-- packages/eslint-plugin/src/rules/camelcase.ts | 3 ++- .../eslint-plugin/src/rules/class-name-casing.ts | 8 ++++++-- .../src/rules/explicit-function-return-type.ts | 6 ++++-- .../src/rules/explicit-member-accessibility.ts | 2 +- .../src/rules/generic-type-naming.ts | 10 ++++++---- packages/eslint-plugin/src/rules/indent.ts | 3 ++- .../src/rules/interface-name-prefix.ts | 4 +++- .../eslint-plugin/src/rules/member-naming.ts | 2 +- .../eslint-plugin/src/rules/member-ordering.ts | 2 +- .../src/rules/no-angle-bracket-type-assertion.ts | 2 +- .../src/rules/no-array-constructor.ts | 2 +- .../src/rules/no-empty-interface.ts | 2 +- .../eslint-plugin/src/rules/no-explicit-any.ts | 2 +- .../src/rules/no-extraneous-class.ts | 2 +- .../src/rules/no-inferrable-types.ts | 2 +- .../eslint-plugin/src/rules/no-misused-new.ts | 2 +- packages/eslint-plugin/src/rules/no-namespace.ts | 2 +- .../src/rules/no-non-null-assertion.ts | 2 +- .../rules/no-object-literal-type-assertion.ts | 2 +- .../src/rules/no-parameter-properties.ts | 2 +- .../eslint-plugin/src/rules/no-this-alias.ts | 2 +- .../src/rules/no-triple-slash-reference.ts | 2 +- .../eslint-plugin/src/rules/no-type-alias.ts | 2 +- .../eslint-plugin/src/rules/no-unused-vars.ts | 2 +- .../src/rules/no-use-before-define.ts | 2 +- .../eslint-plugin/src/rules/no-var-requires.ts | 2 +- .../eslint-plugin/src/rules/prefer-interface.ts | 2 +- .../src/rules/prefer-namespace-keyword.ts | 2 +- .../src/rules/restrict-plus-operands.ts | 2 +- .../src/rules/type-annotation-spacing.ts | 2 +- .../eslint-plugin/tests/rules/ban-types.test.ts | 5 ++--- .../eslint-plugin/tests/rules/indent.test.ts | 9 +-------- packages/typescript-estree/package.json | 2 +- yarn.lock | 8 ++++---- 40 files changed, 89 insertions(+), 70 deletions(-) diff --git a/package.json b/package.json index c7a27e9a643d..20e0a658bef9 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "contributors": [ "James Henry ", "Nicholas C. Zakas", - "Brad Zacher", + "Brad Zacher ", "armano2", "Jed Fox" ], @@ -65,8 +65,8 @@ "@types/semver": "^5.5.0", "cz-conventional-changelog": "2.1.0", "eslint": "^5.12.1", - "eslint-plugin-jest": "^22.1.3", "eslint-plugin-eslint-plugin": "^2.0.1", + "eslint-plugin-jest": "^22.1.3", "glob": "7.1.2", "husky": "0.14.3", "jest": "23.6.0", @@ -77,6 +77,6 @@ "rimraf": "^2.6.3", "ts-jest": "^23.10.4", "tslint": "^5.11.0", - "typescript": "~3.2.1" + "typescript": "^3.3.1" } } diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index ee16a90aa80c..118b23b5ad79 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -30,7 +30,7 @@ "test": "jest --coverage", "recommended:update": "ts-node tools/update-recommended.ts", "prebuild": "npm run clean", - "build": "tsc", + "build": "tsc -p tsconfig.build.json", "clean": "rimraf dist/" }, "dependencies": { @@ -38,13 +38,12 @@ "requireindex": "^1.2.0" }, "devDependencies": { - "eslint": "^5.12.1", "eslint-docs": "^0.2.6", "ts-node": "^8.0.1", "@typescript-eslint/typescript-estree": "1.1.0" }, "peerDependencies": { "eslint": ">=4.13.1 < 6", - "typescript": "~3.2.1" + "typescript": "*" } } diff --git a/packages/eslint-plugin/src/index.ts b/packages/eslint-plugin/src/index.ts index db3ad4e94002..64e0a102febf 100644 --- a/packages/eslint-plugin/src/index.ts +++ b/packages/eslint-plugin/src/index.ts @@ -17,9 +17,19 @@ import recommended from './configs/recommended.json'; // Plugin Definition //------------------------------------------------------------------------------ +const rules = requireIndex(path.join(__dirname, 'rules')); +// eslint expects the rule to be on rules[name], not rules[name].default +const rulesWithoutDefault = Object.keys(rules).reduce>( + (acc, ruleName) => { + acc[ruleName] = rules[ruleName].default; + return acc; + }, + {} +); + // import all rules in lib/rules export = { - rules: requireIndex(path.join(__dirname, 'rules')), + rules: rulesWithoutDefault, configs: { recommended } diff --git a/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts b/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts index 6aeaff6184a9..4adcf6edbf34 100644 --- a/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts +++ b/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts @@ -11,6 +11,9 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ +type Options = []; +type MessageIds = 'adjacentSignature'; + type RuleNode = | TSESTree.ClassBody | TSESTree.Program @@ -19,7 +22,7 @@ type RuleNode = | TSESTree.TSInterfaceBody; type Member = TSESTree.ClassElement | TSESTree.Statement | TSESTree.TypeElement; -const rule: RuleModule<'adjacentSignature', []> = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { @@ -157,4 +160,5 @@ const rule: RuleModule<'adjacentSignature', []> = { }; } }; -export = rule; +export default rule; +export { Options, MessageIds }; diff --git a/packages/eslint-plugin/src/rules/array-type.ts b/packages/eslint-plugin/src/rules/array-type.ts index 62df78f5cd44..bbe4ea13337f 100644 --- a/packages/eslint-plugin/src/rules/array-type.ts +++ b/packages/eslint-plugin/src/rules/array-type.ts @@ -77,16 +77,15 @@ function typeNeedsParentheses(node: TSESTree.Node): boolean { //------------------------------------------------------------------------------ type Options = ['array' | 'generic' | 'array-simple']; - -const defaultOptions: Options = ['array']; - -const rule: RuleModule< +type MessageIds = | 'errorStringGeneric' | 'errorStringGenericSimple' | 'errorStringArray' - | 'errorStringArraySimple', - Options -> = { + | 'errorStringArraySimple'; + +const defaultOptions: Options = ['array']; + +const rule: RuleModule = { meta: { type: 'suggestion', docs: { @@ -255,4 +254,5 @@ const rule: RuleModule< }; } }; -export = rule; +export default rule; +export { Options, MessageIds }; diff --git a/packages/eslint-plugin/src/rules/ban-types.ts b/packages/eslint-plugin/src/rules/ban-types.ts index a66deb8da649..2032b21db1e7 100644 --- a/packages/eslint-plugin/src/rules/ban-types.ts +++ b/packages/eslint-plugin/src/rules/ban-types.ts @@ -24,6 +24,7 @@ type Options = [ >; } ]; +type MessageIds = 'bannedTypeMessage'; const defaultOptions: Options = [ { @@ -52,7 +53,7 @@ const defaultOptions: Options = [ } ]; -const rule: RuleModule<'bannedTypeMessage', Options> = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { @@ -137,4 +138,5 @@ const rule: RuleModule<'bannedTypeMessage', Options> = { }; } }; -export = rule; +export default rule; +export { Options, MessageIds }; diff --git a/packages/eslint-plugin/src/rules/camelcase.ts b/packages/eslint-plugin/src/rules/camelcase.ts index b7b6a5ccd1f7..914f8ffeb8d9 100644 --- a/packages/eslint-plugin/src/rules/camelcase.ts +++ b/packages/eslint-plugin/src/rules/camelcase.ts @@ -131,4 +131,5 @@ const rule: RuleModule = { }; } }; -export = rule; +export default rule; +export { Options, MessageIds }; diff --git a/packages/eslint-plugin/src/rules/class-name-casing.ts b/packages/eslint-plugin/src/rules/class-name-casing.ts index e035c1c06004..bb3bdcda6cb3 100644 --- a/packages/eslint-plugin/src/rules/class-name-casing.ts +++ b/packages/eslint-plugin/src/rules/class-name-casing.ts @@ -12,7 +12,10 @@ import { TSESTree } from '@typescript-eslint/typescript-estree'; // Rule Definition //------------------------------------------------------------------------------ -const rule: RuleModule<'notPascalCased', []> = { +type Options = []; +type MessageIds = 'notPascalCased'; + +const rule: RuleModule = { meta: { type: 'suggestion', docs: { @@ -102,4 +105,5 @@ const rule: RuleModule<'notPascalCased', []> = { }; } }; -export = rule; +export default rule; +export { Options, MessageIds }; diff --git a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts index 2c3cc1b171cd..e37d77cef210 100644 --- a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts +++ b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts @@ -15,6 +15,7 @@ type Options = [ allowExpressions?: boolean; } ]; +type MessageIds = 'missingReturnType'; const defaultOptions: Options = [ { @@ -22,7 +23,7 @@ const defaultOptions: Options = [ } ]; -const rule: RuleModule<'missingReturnType', Options> = { +const rule: RuleModule = { meta: { type: 'problem', docs: { @@ -129,4 +130,5 @@ const rule: RuleModule<'missingReturnType', Options> = { }; } }; -export = rule; +export default rule; +export { Options, MessageIds }; diff --git a/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts index bc2e45ec3873..aedf0033801a 100644 --- a/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts +++ b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts @@ -88,4 +88,4 @@ const rule: RuleModule<'missingAccessibility', []> = { }; } }; -export = rule; +export default rule; diff --git a/packages/eslint-plugin/src/rules/generic-type-naming.ts b/packages/eslint-plugin/src/rules/generic-type-naming.ts index f04a414c3e79..6d68a9364cb3 100644 --- a/packages/eslint-plugin/src/rules/generic-type-naming.ts +++ b/packages/eslint-plugin/src/rules/generic-type-naming.ts @@ -6,14 +6,15 @@ import { TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; -type Options = [string]; +type Options = [string?]; +type MessageIds = 'paramNotMatchRule'; const defaultOptions: Options = [ // Matches: T , TA , TAbc , TA1Bca , T1 , T2 '^T([A-Z0-9][a-zA-Z0-9]*){0,1}$' ]; -const rule: RuleModule<'paramNotMatchRule', Options> = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { @@ -33,7 +34,7 @@ const rule: RuleModule<'paramNotMatchRule', Options> = { }, create(context) { - const rule = util.applyDefault(defaultOptions, context.options)[0]; + const rule = util.applyDefault(defaultOptions, context.options)[0]!; const regex = new RegExp(rule); return { @@ -54,4 +55,5 @@ const rule: RuleModule<'paramNotMatchRule', Options> = { }; } }; -export = rule; +export default rule; +export { Options, MessageIds }; diff --git a/packages/eslint-plugin/src/rules/indent.ts b/packages/eslint-plugin/src/rules/indent.ts index 72643c69f928..91402a5868eb 100644 --- a/packages/eslint-plugin/src/rules/indent.ts +++ b/packages/eslint-plugin/src/rules/indent.ts @@ -452,4 +452,5 @@ const rule: RuleModule = { }); } }; -export = rule; +export default rule; +export { Options, MessageIds }; diff --git a/packages/eslint-plugin/src/rules/interface-name-prefix.ts b/packages/eslint-plugin/src/rules/interface-name-prefix.ts index 54a89ff05c01..1d777bf58ba2 100644 --- a/packages/eslint-plugin/src/rules/interface-name-prefix.ts +++ b/packages/eslint-plugin/src/rules/interface-name-prefix.ts @@ -11,6 +11,7 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ type Options = ['never' | 'always']; +type MessageIds = 'noPrefix'; const defaultOptions: Options = ['never']; @@ -78,4 +79,5 @@ const rule: RuleModule<'noPrefix', Options> = { }; } }; -export = rule; +export default rule; +export { Options, MessageIds }; diff --git a/packages/eslint-plugin/src/rules/member-naming.ts b/packages/eslint-plugin/src/rules/member-naming.ts index cb7866f40975..2436c56eee6c 100644 --- a/packages/eslint-plugin/src/rules/member-naming.ts +++ b/packages/eslint-plugin/src/rules/member-naming.ts @@ -102,4 +102,4 @@ const rule: RuleModule = { }; } }; -export = rule; +export default rule; diff --git a/packages/eslint-plugin/src/rules/member-ordering.ts b/packages/eslint-plugin/src/rules/member-ordering.ts index 872e5c64d7b5..fa5a30316599 100644 --- a/packages/eslint-plugin/src/rules/member-ordering.ts +++ b/packages/eslint-plugin/src/rules/member-ordering.ts @@ -390,4 +390,4 @@ const rule: RuleModule = { }; } }; -export = rule; +export default rule; diff --git a/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts b/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts index d457b709e590..a34af0e3cad1 100644 --- a/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts @@ -44,4 +44,4 @@ const rule: RuleModule = { }; } }; -export = rule; +export default rule; diff --git a/packages/eslint-plugin/src/rules/no-array-constructor.ts b/packages/eslint-plugin/src/rules/no-array-constructor.ts index 8c3bff08cf41..82715a6332f0 100644 --- a/packages/eslint-plugin/src/rules/no-array-constructor.ts +++ b/packages/eslint-plugin/src/rules/no-array-constructor.ts @@ -63,4 +63,4 @@ const rule: RuleModule = { }; } }; -export = rule; +export default rule; diff --git a/packages/eslint-plugin/src/rules/no-empty-interface.ts b/packages/eslint-plugin/src/rules/no-empty-interface.ts index 65590af0b5e6..5ca9a111da00 100644 --- a/packages/eslint-plugin/src/rules/no-empty-interface.ts +++ b/packages/eslint-plugin/src/rules/no-empty-interface.ts @@ -51,4 +51,4 @@ const rule: RuleModule = { }; } }; -export = rule; +export default rule; diff --git a/packages/eslint-plugin/src/rules/no-explicit-any.ts b/packages/eslint-plugin/src/rules/no-explicit-any.ts index 01b810c44a26..97a7198a1d7e 100644 --- a/packages/eslint-plugin/src/rules/no-explicit-any.ts +++ b/packages/eslint-plugin/src/rules/no-explicit-any.ts @@ -35,4 +35,4 @@ const rule: RuleModule = { }; } }; -export = rule; +export default rule; diff --git a/packages/eslint-plugin/src/rules/no-extraneous-class.ts b/packages/eslint-plugin/src/rules/no-extraneous-class.ts index 850a688ca2dc..e1243623fa1c 100644 --- a/packages/eslint-plugin/src/rules/no-extraneous-class.ts +++ b/packages/eslint-plugin/src/rules/no-extraneous-class.ts @@ -110,4 +110,4 @@ const rule: RuleModule = { }; } }; -export = rule; +export default rule; diff --git a/packages/eslint-plugin/src/rules/no-inferrable-types.ts b/packages/eslint-plugin/src/rules/no-inferrable-types.ts index 5d08c1093cc2..9f004488c3fa 100644 --- a/packages/eslint-plugin/src/rules/no-inferrable-types.ts +++ b/packages/eslint-plugin/src/rules/no-inferrable-types.ts @@ -184,4 +184,4 @@ const rule: RuleModule = { }; } }; -export = rule; +export default rule; diff --git a/packages/eslint-plugin/src/rules/no-misused-new.ts b/packages/eslint-plugin/src/rules/no-misused-new.ts index 319804f1a8b9..f51b3c916611 100644 --- a/packages/eslint-plugin/src/rules/no-misused-new.ts +++ b/packages/eslint-plugin/src/rules/no-misused-new.ts @@ -96,4 +96,4 @@ const rule: RuleModule = { }; } }; -export = rule; +export default rule; diff --git a/packages/eslint-plugin/src/rules/no-namespace.ts b/packages/eslint-plugin/src/rules/no-namespace.ts index e2eaec925fc0..a1b79700f1b1 100644 --- a/packages/eslint-plugin/src/rules/no-namespace.ts +++ b/packages/eslint-plugin/src/rules/no-namespace.ts @@ -76,4 +76,4 @@ const rule: RuleModule = { }; } }; -export = rule; +export default rule; diff --git a/packages/eslint-plugin/src/rules/no-non-null-assertion.ts b/packages/eslint-plugin/src/rules/no-non-null-assertion.ts index 9d795f570cb3..f4f4236e29ac 100644 --- a/packages/eslint-plugin/src/rules/no-non-null-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-non-null-assertion.ts @@ -38,4 +38,4 @@ const rule: RuleModule = { }; } }; -export = rule; +export default rule; diff --git a/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts b/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts index 066fedae4c58..db99344a279c 100644 --- a/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts @@ -93,4 +93,4 @@ const rule: RuleModule = { }; } }; -export = rule; +export default rule; diff --git a/packages/eslint-plugin/src/rules/no-parameter-properties.ts b/packages/eslint-plugin/src/rules/no-parameter-properties.ts index e975e205c36e..fa6856de7ce5 100644 --- a/packages/eslint-plugin/src/rules/no-parameter-properties.ts +++ b/packages/eslint-plugin/src/rules/no-parameter-properties.ts @@ -95,4 +95,4 @@ const rule: RuleModule = { }; } }; -export = rule; +export default rule; diff --git a/packages/eslint-plugin/src/rules/no-this-alias.ts b/packages/eslint-plugin/src/rules/no-this-alias.ts index b9e08476fada..1007adddd91b 100644 --- a/packages/eslint-plugin/src/rules/no-this-alias.ts +++ b/packages/eslint-plugin/src/rules/no-this-alias.ts @@ -75,4 +75,4 @@ const rule: RuleModule = { }; } }; -export = rule; +export default rule; diff --git a/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts b/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts index cd0b1f06fe5a..696ed50f07cd 100644 --- a/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts +++ b/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts @@ -62,4 +62,4 @@ const rule: RuleModule = { }; } }; -export = rule; +export default rule; diff --git a/packages/eslint-plugin/src/rules/no-type-alias.ts b/packages/eslint-plugin/src/rules/no-type-alias.ts index d54b06938593..9a083be2448e 100644 --- a/packages/eslint-plugin/src/rules/no-type-alias.ts +++ b/packages/eslint-plugin/src/rules/no-type-alias.ts @@ -296,4 +296,4 @@ const rule: RuleModule = { }; } }; -export = rule; +export default rule; diff --git a/packages/eslint-plugin/src/rules/no-unused-vars.ts b/packages/eslint-plugin/src/rules/no-unused-vars.ts index c4daf7fb0cc7..e4603a61f831 100644 --- a/packages/eslint-plugin/src/rules/no-unused-vars.ts +++ b/packages/eslint-plugin/src/rules/no-unused-vars.ts @@ -101,4 +101,4 @@ const rule: Rule.RuleModule = Object.assign({}, baseRule, { }); } }); -export = rule; +export default rule; diff --git a/packages/eslint-plugin/src/rules/no-use-before-define.ts b/packages/eslint-plugin/src/rules/no-use-before-define.ts index 1a30fb44c0cd..f923a9259466 100644 --- a/packages/eslint-plugin/src/rules/no-use-before-define.ts +++ b/packages/eslint-plugin/src/rules/no-use-before-define.ts @@ -297,4 +297,4 @@ const rule: RuleModule = { }; } }; -export = rule; +export default rule; diff --git a/packages/eslint-plugin/src/rules/no-var-requires.ts b/packages/eslint-plugin/src/rules/no-var-requires.ts index 0a1be13c08e0..da79fc82d2d1 100644 --- a/packages/eslint-plugin/src/rules/no-var-requires.ts +++ b/packages/eslint-plugin/src/rules/no-var-requires.ts @@ -43,4 +43,4 @@ const rule: RuleModule = { }; } }; -export = rule; +export default rule; diff --git a/packages/eslint-plugin/src/rules/prefer-interface.ts b/packages/eslint-plugin/src/rules/prefer-interface.ts index 4972fddb4de9..9c7533cf8a78 100644 --- a/packages/eslint-plugin/src/rules/prefer-interface.ts +++ b/packages/eslint-plugin/src/rules/prefer-interface.ts @@ -67,4 +67,4 @@ const rule: RuleModule = { }; } }; -export = rule; +export default rule; diff --git a/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts b/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts index d8a828ec0290..9a7594777274 100644 --- a/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts +++ b/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts @@ -59,4 +59,4 @@ const rule: RuleModule = { }; } }; -export = rule; +export default rule; diff --git a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts index 1280c592d717..a5346136421a 100644 --- a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts +++ b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts @@ -105,4 +105,4 @@ const rule: RuleModule = { }; } }; -export = rule; +export default rule; diff --git a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts index 3511279b537e..385a0aa61698 100644 --- a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts +++ b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts @@ -187,4 +187,4 @@ const rule: RuleModule = { }; } }; -export = rule; +export default rule; diff --git a/packages/eslint-plugin/tests/rules/ban-types.test.ts b/packages/eslint-plugin/tests/rules/ban-types.test.ts index 00905e575f53..1fb9946241d9 100644 --- a/packages/eslint-plugin/tests/rules/ban-types.test.ts +++ b/packages/eslint-plugin/tests/rules/ban-types.test.ts @@ -7,7 +7,7 @@ // Requirements //------------------------------------------------------------------------------ -import rule from '../../src/rules/ban-types'; +import rule, { Options } from '../../src/rules/ban-types'; import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ @@ -18,8 +18,7 @@ const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); -// TODO - figure out a better way to type this that doesn't break the generics -const options: any = [ +const options: Options = [ { types: { String: { diff --git a/packages/eslint-plugin/tests/rules/indent.test.ts b/packages/eslint-plugin/tests/rules/indent.test.ts index 07234f7526bf..57f3907374d2 100644 --- a/packages/eslint-plugin/tests/rules/indent.test.ts +++ b/packages/eslint-plugin/tests/rules/indent.test.ts @@ -8,15 +8,8 @@ // Requirements //------------------------------------------------------------------------------ -import rule from '../../src/rules/indent'; +import rule, { Options, MessageIds } from '../../src/rules/indent'; import RuleTester, { RunTests, TestCaseError } from '../RuleTester'; -import { - InferOptionsTypeFromRule, - InferMessageIdsTypeFromRule -} from '../../src/tsestree-utils'; - -type Options = InferOptionsTypeFromRule; -type MessageIds = InferMessageIdsTypeFromRule; /** * Marks a test case as a plain javascript case which should be indented the same diff --git a/packages/typescript-estree/package.json b/packages/typescript-estree/package.json index a8490f513a68..2dfd4ce31fc3 100644 --- a/packages/typescript-estree/package.json +++ b/packages/typescript-estree/package.json @@ -42,6 +42,6 @@ }, "devDependencies": { "@typescript-eslint/shared-fixtures": "1.1.0", - "typescript": "~3.2.1" + "typescript": "~3.3.1" } } diff --git a/yarn.lock b/yarn.lock index c3cfb2d8feec..1cdcf96918aa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6887,10 +6887,10 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript@~3.2.1: - version "3.2.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.4.tgz#c585cb952912263d915b462726ce244ba510ef3d" - integrity sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg== +typescript@^3.3.1, typescript@~3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.3.1.tgz#6de14e1db4b8a006ac535e482c8ba018c55f750b" + integrity sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA== uglify-js@^3.1.4: version "3.4.9" From 67c2ded153476ec30c35d5545e0d9ecbdf7824a9 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Fri, 1 Feb 2019 10:35:12 -0800 Subject: [PATCH 39/92] fix config so the test files get the proper types from src --- packages/eslint-plugin/tsconfig.build.json | 9 +++++++++ packages/eslint-plugin/tsconfig.json | 14 +++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 packages/eslint-plugin/tsconfig.build.json diff --git a/packages/eslint-plugin/tsconfig.build.json b/packages/eslint-plugin/tsconfig.build.json new file mode 100644 index 000000000000..b2fcd92b4b8b --- /dev/null +++ b/packages/eslint-plugin/tsconfig.build.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "declaration": false, + "outDir": "./dist", + "resolveJsonModule": true + }, + "include": ["src", "typings"] +} diff --git a/packages/eslint-plugin/tsconfig.json b/packages/eslint-plugin/tsconfig.json index b2fcd92b4b8b..7418d4448682 100644 --- a/packages/eslint-plugin/tsconfig.json +++ b/packages/eslint-plugin/tsconfig.json @@ -1,9 +1,9 @@ { - "extends": "../../tsconfig.json", - "compilerOptions": { - "declaration": false, - "outDir": "./dist", - "resolveJsonModule": true - }, - "include": ["src", "typings"] + "extends": "./tsconfig.build.json", + "include": [ + "src", + "typings", + "tests", + "tools" + ] } From 9eb59cb7e92543d3bdd3296adf4e0db374f0403a Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Fri, 1 Feb 2019 10:35:27 -0800 Subject: [PATCH 40/92] member-delimiter-style --- .../src/rules/member-delimiter-style.ts | 72 ++++++++++++------- packages/eslint-plugin/typings/ts-eslint.d.ts | 8 ++- packages/typescript-estree/src/typedefs.ts | 21 +++--- 3 files changed, 62 insertions(+), 39 deletions(-) diff --git a/packages/eslint-plugin/src/rules/member-delimiter-style.ts b/packages/eslint-plugin/src/rules/member-delimiter-style.ts index ed980361d593..8d92b8588212 100644 --- a/packages/eslint-plugin/src/rules/member-delimiter-style.ts +++ b/packages/eslint-plugin/src/rules/member-delimiter-style.ts @@ -4,6 +4,7 @@ * @author Brad Zacher */ +import { TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; @@ -12,23 +13,28 @@ import * as util from '../util'; //------------------------------------------------------------------------------ type Delimiter = 'comma' | 'none' | 'semi'; +interface TypeOptions { + delimiter?: Delimiter; + requireLast?: boolean; +} interface BaseOptions { - multiline: { - delimiter: Delimiter; - requireLast: boolean; - }; - singleline: { - delimiter: Delimiter; - requireLast: boolean; - }; + multiline?: TypeOptions; + singleline?: TypeOptions; } -interface Options extends BaseOptions { +interface Config extends BaseOptions { overrides?: { typeLiteral?: BaseOptions; interface?: BaseOptions; }; } -const defaultOptions: Options[] = [ +type Options = [Config]; +type MessageIds = + | 'unexpectedComma' + | 'unexpectedSemi' + | 'expectedComma' + | 'expectedSemi'; + +const defaultOptions: Options = [ { multiline: { delimiter: 'semi', @@ -65,13 +71,13 @@ const definition = { additionalProperties: false }; -const rule: RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { description: 'Require a specific member delimiter style for interfaces and type literals', - category: 'TypeScript', + category: 'Stylistic Issues', url: util.metaDocsUrl('member-delimiter-style'), recommended: 'error' }, @@ -107,8 +113,11 @@ const rule: RuleModule = { // use the base options as the defaults for the cases const baseOptions = options; const overrides = baseOptions.overrides || {}; - const interfaceOptions = util.deepMerge(baseOptions, overrides.interface); - const typeLiteralOptions = util.deepMerge( + const interfaceOptions: BaseOptions = util.deepMerge( + baseOptions, + overrides.interface + ); + const typeLiteralOptions: BaseOptions = util.deepMerge( baseOptions, overrides.typeLiteral ); @@ -119,14 +128,16 @@ const rule: RuleModule = { /** * Check the last token in the given member. - * @param {ASTNode} member the member to be evaluated. - * @param {Object} opts the options to be validated. - * @param {boolean} isLast a flag indicating `member` is the last in the + * @param member the member to be evaluated. + * @param opts the options to be validated. + * @param isLast a flag indicating `member` is the last in the * interface or type literal. - * @returns {void} - * @private */ - function checkLastToken(member, opts, isLast) { + function checkLastToken( + member: TSESTree.TypeElement, + opts: TypeOptions, + isLast: boolean + ): void { /** * Resolves the boolean value for the given setting enum value * @param type the option name @@ -139,11 +150,14 @@ const rule: RuleModule = { return opts.delimiter === type; } - let messageId; + let messageId: MessageIds | null = null; let missingDelimiter = false; const lastToken = sourceCode.getLastToken(member, { includeComments: false }); + if (!lastToken) { + return; + } const optsSemi = getOption('semi'); const optsComma = getOption('comma'); @@ -211,17 +225,20 @@ const rule: RuleModule = { * Check the member separator being used matches the delimiter. * @param {ASTNode} node the node to be evaluated. */ - function checkMemberSeparatorStyle(node): void { - const isInterface = node.type === 'TSInterfaceBody'; + function checkMemberSeparatorStyle( + node: TSESTree.TSInterfaceBody | TSESTree.TSTypeLiteral + ): void { const isSingleLine = node.loc.start.line === node.loc.end.line; - const members = isInterface ? node.body : node.members; + const members = + node.type === 'TSInterfaceBody' ? node.body : node.members; - const typeOpts = isInterface ? interfaceOptions : typeLiteralOptions; + const typeOpts = + node.type === 'TSInterfaceBody' ? interfaceOptions : typeLiteralOptions; const opts = isSingleLine ? typeOpts.singleline : typeOpts.multiline; members.forEach((member, index) => { - checkLastToken(member, opts, index === members.length - 1); + checkLastToken(member, opts || {}, index === members.length - 1); }); } @@ -235,4 +252,5 @@ const rule: RuleModule = { }; } }; -export = rule; +export default rule; +export { Options, MessageIds }; diff --git a/packages/eslint-plugin/typings/ts-eslint.d.ts b/packages/eslint-plugin/typings/ts-eslint.d.ts index 51f6a91380c7..808bb9096678 100644 --- a/packages/eslint-plugin/typings/ts-eslint.d.ts +++ b/packages/eslint-plugin/typings/ts-eslint.d.ts @@ -308,9 +308,13 @@ declare module 'ts-eslint' { */ messageId: TMessageIds; /** - * The Node which the report is being attached to + * The Node or AST Token which the report is being attached to */ - node: TSESTree.Node; + node: TSESTree.Node | AST.Token; + /** + * An override of the location of the report + */ + loc?: TSESTree.NodeLocation; } interface RuleContext { diff --git a/packages/typescript-estree/src/typedefs.ts b/packages/typescript-estree/src/typedefs.ts index a84acda142dd..f8fac2f818ff 100644 --- a/packages/typescript-estree/src/typedefs.ts +++ b/packages/typescript-estree/src/typedefs.ts @@ -8,21 +8,22 @@ export interface LineAndColumnData { */ column: number; } +export interface NodeLocation { + /** + * The position of the first character of the parsed source region + */ + start: LineAndColumnData; + /** + * The position of the first character after the parsed source region + */ + end: LineAndColumnData; +} interface NodeBase { /** * The source location information of the node. */ - loc: { - /** - * The position of the first character of the parsed source region - */ - start: LineAndColumnData; - /** - * The position of the first character after the parsed source region - */ - end: LineAndColumnData; - }; + loc: NodeLocation; /** * An array of two numbers. * Both numbers are a 0-based index which is the position in the array of source code characters. From 393204f04a1c070c20e361c2a66e568f071f4973 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Fri, 1 Feb 2019 17:23:30 -0800 Subject: [PATCH 41/92] revert typescript version bump --- package.json | 2 +- packages/typescript-estree/package.json | 2 +- yarn.lock | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 20e0a658bef9..29a052c35c6c 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,6 @@ "rimraf": "^2.6.3", "ts-jest": "^23.10.4", "tslint": "^5.11.0", - "typescript": "^3.3.1" + "typescript": "~3.2.1" } } diff --git a/packages/typescript-estree/package.json b/packages/typescript-estree/package.json index 2dfd4ce31fc3..a8490f513a68 100644 --- a/packages/typescript-estree/package.json +++ b/packages/typescript-estree/package.json @@ -42,6 +42,6 @@ }, "devDependencies": { "@typescript-eslint/shared-fixtures": "1.1.0", - "typescript": "~3.3.1" + "typescript": "~3.2.1" } } diff --git a/yarn.lock b/yarn.lock index 1cdcf96918aa..c3cfb2d8feec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6887,10 +6887,10 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript@^3.3.1, typescript@~3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.3.1.tgz#6de14e1db4b8a006ac535e482c8ba018c55f750b" - integrity sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA== +typescript@~3.2.1: + version "3.2.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.4.tgz#c585cb952912263d915b462726ce244ba510ef3d" + integrity sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg== uglify-js@^3.1.4: version "3.4.9" From 7ce246fd849fd002d4ff9e2724c87f0d6dd61774 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Fri, 1 Feb 2019 17:28:04 -0800 Subject: [PATCH 42/92] review fixes 1/n --- .../typescript-estree/src/ast-node-types.ts | 2 + packages/typescript-estree/src/typedefs.ts | 620 +++++++++--------- 2 files changed, 313 insertions(+), 309 deletions(-) diff --git a/packages/typescript-estree/src/ast-node-types.ts b/packages/typescript-estree/src/ast-node-types.ts index a5e69a66d076..aa370d2e97a1 100644 --- a/packages/typescript-estree/src/ast-node-types.ts +++ b/packages/typescript-estree/src/ast-node-types.ts @@ -104,12 +104,14 @@ export enum AST_NODE_TYPES { TSBooleanKeyword = 'TSBooleanKeyword', TSBigIntKeyword = 'TSBigIntKeyword', TSConditionalType = 'TSConditionalType', + TSConstKeyword = 'TSConstKeyword', TSConstructorType = 'TSConstructorType', TSCallSignatureDeclaration = 'TSCallSignatureDeclaration', TSClassImplements = 'TSClassImplements', TSConstructSignatureDeclaration = 'TSConstructSignatureDeclaration', TSDeclareKeyword = 'TSDeclareKeyword', TSDeclareFunction = 'TSDeclareFunction', + TSDefaultKeyword = 'TSDefaultKeyword', TSEnumDeclaration = 'TSEnumDeclaration', TSEnumMember = 'TSEnumMember', TSExportAssignment = 'TSExportAssignment', diff --git a/packages/typescript-estree/src/typedefs.ts b/packages/typescript-estree/src/typedefs.ts index f8fac2f818ff..f52fa9e221f6 100644 --- a/packages/typescript-estree/src/typedefs.ts +++ b/packages/typescript-estree/src/typedefs.ts @@ -1,3 +1,5 @@ +import { AST_NODE_TYPES } from './ast-node-types'; + export interface LineAndColumnData { /** * Line number (1-indexed) @@ -8,7 +10,7 @@ export interface LineAndColumnData { */ column: number; } -export interface NodeLocation { +export interface SourceLocation { /** * The position of the first character of the parsed source region */ @@ -19,11 +21,11 @@ export interface NodeLocation { end: LineAndColumnData; } -interface NodeBase { +interface BaseNode { /** * The source location information of the node. */ - loc: NodeLocation; + loc: SourceLocation; /** * An array of two numbers. * Both numbers are a 0-based index which is the position in the array of source code characters. @@ -403,13 +405,13 @@ export type TSUnaryExpression = // **Ensure you sort the interfaces alphabetically** /////////////// -interface BinaryExpressionBase extends NodeBase { +interface BinaryExpressionBase extends BaseNode { operator: string; left: Expression; right: Expression; } -interface ClassDeclarationBase extends NodeBase { +interface ClassDeclarationBase extends BaseNode { typeParameters?: TSTypeParameterDeclaration; superTypeParameters?: TSTypeParameterInstantiation; id?: Identifier; @@ -421,7 +423,7 @@ interface ClassDeclarationBase extends NodeBase { decorators?: Decorator[]; } -interface ClassPropertyBase extends NodeBase { +interface ClassPropertyBase extends BaseNode { key: PropertyName; value: Expression; computed: boolean; @@ -434,7 +436,7 @@ interface ClassPropertyBase extends NodeBase { typeAnnotation?: TSTypeAnnotation; } -interface FunctionDeclarationBase extends NodeBase { +interface FunctionDeclarationBase extends BaseNode { id: Identifier | null; generator: boolean; expression: boolean; @@ -445,13 +447,13 @@ interface FunctionDeclarationBase extends NodeBase { typeParameters?: TSTypeParameterDeclaration; } -interface FunctionSignatureBase extends NodeBase { +interface FunctionSignatureBase extends BaseNode { params: Parameter[]; returnType?: TSTypeAnnotation; typeParameters?: TSTypeParameterDeclaration; } -interface LiteralBase extends NodeBase { +interface LiteralBase extends BaseNode { raw: boolean | number | RegExp | string | null; value: string; regex?: { @@ -460,7 +462,7 @@ interface LiteralBase extends NodeBase { }; } -interface MethodDefinitionBase extends NodeBase { +interface MethodDefinitionBase extends BaseNode { key: PropertyName; value: FunctionExpression; computed: boolean; @@ -471,12 +473,12 @@ interface MethodDefinitionBase extends NodeBase { typeParameters?: TSTypeParameterDeclaration; } -interface TSHeritageBase extends NodeBase { +interface TSHeritageBase extends BaseNode { expression: Expression; typeParameters?: TSTypeParameterDeclaration; } -interface UnaryExpressionBase extends NodeBase { +interface UnaryExpressionBase extends BaseNode { operator: string; prefix: boolean; argument: LeftHandSideExpression | Literal | UnaryExpression; @@ -487,20 +489,20 @@ interface UnaryExpressionBase extends NodeBase { // **Ensure you sort the interfaces alphabetically** /////////////// -export interface ArrayExpression extends NodeBase { - type: 'ArrayExpression'; +export interface ArrayExpression extends BaseNode { + type: AST_NODE_TYPES.ArrayExpression; elements: Expression[]; } -export interface ArrayPattern extends NodeBase { - type: 'ArrayPattern'; +export interface ArrayPattern extends BaseNode { + type: AST_NODE_TYPES.ArrayPattern; elements: Expression[]; typeAnnotation?: TSTypeAnnotation; optional?: boolean; } -export interface ArrowFunctionExpression extends NodeBase { - type: 'ArrowFunctionExpression'; +export interface ArrowFunctionExpression extends BaseNode { + type: AST_NODE_TYPES.ArrowFunctionExpression; generator: boolean; id: null; params: Parameter[]; @@ -512,151 +514,151 @@ export interface ArrowFunctionExpression extends NodeBase { } export interface AssignmentExpression extends BinaryExpressionBase { - type: 'AssignmentExpression'; + type: AST_NODE_TYPES.AssignmentExpression; } -export interface AssignmentPattern extends NodeBase { - type: 'AssignmentPattern'; +export interface AssignmentPattern extends BaseNode { + type: AST_NODE_TYPES.AssignmentPattern; left: BindingName; right?: Expression; typeAnnotation?: TSTypeAnnotation; optional?: boolean; } -export interface AwaitExpression extends NodeBase { - type: 'AwaitExpression'; +export interface AwaitExpression extends BaseNode { + type: AST_NODE_TYPES.AwaitExpression; argument: TSUnaryExpression; } export interface BigIntLiteral extends LiteralBase { - type: 'BigIntLiteral'; + type: AST_NODE_TYPES.BigIntLiteral; } export interface BinaryExpression extends BinaryExpressionBase { - type: 'BinaryExpression'; + type: AST_NODE_TYPES.BinaryExpression; } -export interface BlockStatement extends NodeBase { - type: 'BlockStatement'; +export interface BlockStatement extends BaseNode { + type: AST_NODE_TYPES.BlockStatement; body: Statement[]; } -export interface BreakStatement extends NodeBase { - type: 'BreakStatement'; +export interface BreakStatement extends BaseNode { + type: AST_NODE_TYPES.BreakStatement; label: Identifier | null; } -export interface CallExpression extends NodeBase { - type: 'CallExpression'; +export interface CallExpression extends BaseNode { + type: AST_NODE_TYPES.CallExpression; callee: LeftHandSideExpression; arguments: Expression[]; typeParameters?: TSTypeParameterInstantiation; } -export interface CatchClause extends NodeBase { - type: 'CatchClause'; +export interface CatchClause extends BaseNode { + type: AST_NODE_TYPES.CatchClause; param: BindingName | null; body: BlockStatement; } -export interface ClassBody extends NodeBase { - type: 'ClassBody'; +export interface ClassBody extends BaseNode { + type: AST_NODE_TYPES.ClassBody; body: ClassElement[]; } export interface ClassDeclaration extends ClassDeclarationBase { - type: 'ClassDeclaration'; + type: AST_NODE_TYPES.ClassDeclaration; } export interface ClassExpression extends ClassDeclarationBase { - type: 'ClassExpression'; + type: AST_NODE_TYPES.ClassExpression; } export interface ClassProperty extends ClassPropertyBase { - type: 'ClassProperty'; + type: AST_NODE_TYPES.ClassProperty; } -export interface Comment extends NodeBase { +export interface Comment extends BaseNode { type: 'Line' | 'Block'; value: string; } -export interface ConditionalExpression extends NodeBase { - type: 'ConditionalExpression'; +export interface ConditionalExpression extends BaseNode { + type: AST_NODE_TYPES.ConditionalExpression; test: Expression; consequent: Expression; alternate: Expression; } -export interface ContinueStatement extends NodeBase { - type: 'ContinueStatement'; +export interface ContinueStatement extends BaseNode { + type: AST_NODE_TYPES.ContinueStatement; label: Identifier | null; } -export interface DebuggerStatement extends NodeBase { - type: 'DebuggerStatement'; +export interface DebuggerStatement extends BaseNode { + type: AST_NODE_TYPES.DebuggerStatement; } -export interface Decorator extends NodeBase { - type: 'Decorator'; +export interface Decorator extends BaseNode { + type: AST_NODE_TYPES.Decorator; expression: LeftHandSideExpression; } -export interface DoWhileStatement extends NodeBase { - type: 'DoWhileStatement'; +export interface DoWhileStatement extends BaseNode { + type: AST_NODE_TYPES.DoWhileStatement; test: Expression; body: Statement; } -export interface EmptyStatement extends NodeBase { - type: 'EmptyStatement'; +export interface EmptyStatement extends BaseNode { + type: AST_NODE_TYPES.EmptyStatement; } -export interface ExportAllDeclaration extends NodeBase { - type: 'ExportAllDeclaration'; +export interface ExportAllDeclaration extends BaseNode { + type: AST_NODE_TYPES.ExportAllDeclaration; source: Expression | null; } -export interface ExportDefaultDeclaration extends NodeBase { - type: 'ExportDefaultDeclaration'; +export interface ExportDefaultDeclaration extends BaseNode { + type: AST_NODE_TYPES.ExportDefaultDeclaration; declaration: ExportDeclaration; } -export interface ExportNamedDeclaration extends NodeBase { - type: 'ExportNamedDeclaration'; +export interface ExportNamedDeclaration extends BaseNode { + type: AST_NODE_TYPES.ExportNamedDeclaration; declaration: ExportDeclaration | null; specifiers: ExportSpecifier[]; source: Expression | null; } -export interface ExportSpecifier extends NodeBase { - type: 'ExportSpecifier'; +export interface ExportSpecifier extends BaseNode { + type: AST_NODE_TYPES.ExportSpecifier; local: Identifier; exported: Identifier; } -export interface ExpressionStatement extends NodeBase { - type: 'ExpressionStatement'; +export interface ExpressionStatement extends BaseNode { + type: AST_NODE_TYPES.ExpressionStatement; expression: Expression; } -export interface ForInStatement extends NodeBase { - type: 'ForInStatement'; +export interface ForInStatement extends BaseNode { + type: AST_NODE_TYPES.ForInStatement; left: ForInitialiser; right: Expression; body: Statement; } -export interface ForOfStatement extends NodeBase { - type: 'ForOfStatement'; +export interface ForOfStatement extends BaseNode { + type: AST_NODE_TYPES.ForOfStatement; left: ForInitialiser; right: Expression; body: Statement; await: boolean; } -export interface ForStatement extends NodeBase { - type: 'ForStatement'; +export interface ForStatement extends BaseNode { + type: AST_NODE_TYPES.ForStatement; init: Expression | ForInitialiser | null; test: Expression | null; update: Expression | null; @@ -664,187 +666,187 @@ export interface ForStatement extends NodeBase { } export interface FunctionDeclaration extends FunctionDeclarationBase { - type: 'FunctionDeclaration'; + type: AST_NODE_TYPES.FunctionDeclaration; } export interface FunctionExpression extends FunctionDeclarationBase { - type: 'FunctionExpression'; + type: AST_NODE_TYPES.FunctionExpression; } -export interface Identifier extends NodeBase { - type: 'Identifier'; +export interface Identifier extends BaseNode { + type: AST_NODE_TYPES.Identifier; name: string; typeAnnotation?: TSTypeAnnotation; optional?: boolean; } -export interface IfStatement extends NodeBase { - type: 'IfStatement'; +export interface IfStatement extends BaseNode { + type: AST_NODE_TYPES.IfStatement; test: Expression; consequent: Statement; alternate: Statement | null; } -export interface Import extends NodeBase { - type: 'Import'; +export interface Import extends BaseNode { + type: AST_NODE_TYPES.Import; } -export interface ImportDeclaration extends NodeBase { - type: 'ImportDeclaration'; +export interface ImportDeclaration extends BaseNode { + type: AST_NODE_TYPES.ImportDeclaration; source: Expression; specifiers: ImportClause[]; } -export interface ImportDefaultSpecifier extends NodeBase { - type: 'ImportDefaultSpecifier'; +export interface ImportDefaultSpecifier extends BaseNode { + type: AST_NODE_TYPES.ImportDefaultSpecifier; local: Identifier; } -export interface ImportNamespaceSpecifier extends NodeBase { - type: 'ImportNamespaceSpecifier'; +export interface ImportNamespaceSpecifier extends BaseNode { + type: AST_NODE_TYPES.ImportNamespaceSpecifier; local: Identifier; } -export interface ImportSpecifier extends NodeBase { - type: 'ImportSpecifier'; +export interface ImportSpecifier extends BaseNode { + type: AST_NODE_TYPES.ImportSpecifier; local: Identifier; imported: Identifier; } -export interface JSXAttribute extends NodeBase { - type: 'JSXAttribute'; +export interface JSXAttribute extends BaseNode { + type: AST_NODE_TYPES.JSXAttribute; name: JSXIdentifier; value: Literal | JSXExpression | null; } -export interface JSXClosingElement extends NodeBase { - type: 'JSXClosingElement'; +export interface JSXClosingElement extends BaseNode { + type: AST_NODE_TYPES.JSXClosingElement; name: JSXTagNameExpression; } -export interface JSXClosingFragment extends NodeBase { - type: 'JSXClosingFragment'; +export interface JSXClosingFragment extends BaseNode { + type: AST_NODE_TYPES.JSXClosingFragment; } -export interface JSXElement extends NodeBase { - type: 'JSXElement'; +export interface JSXElement extends BaseNode { + type: AST_NODE_TYPES.JSXElement; openingElement: JSXOpeningElement; closingElement: JSXClosingElement | null; children: JSXChild[]; } -export interface JSXEmptyExpression extends NodeBase { - type: 'JSXEmptyExpression'; +export interface JSXEmptyExpression extends BaseNode { + type: AST_NODE_TYPES.JSXEmptyExpression; } -export interface JSXExpressionContainer extends NodeBase { - type: 'JSXExpressionContainer'; +export interface JSXExpressionContainer extends BaseNode { + type: AST_NODE_TYPES.JSXExpressionContainer; expression: Expression | JSXEmptyExpression; } -export interface JSXFragment extends NodeBase { - type: 'JSXFragment'; +export interface JSXFragment extends BaseNode { + type: AST_NODE_TYPES.JSXFragment; openingFragment: JSXOpeningFragment; closingFragment: JSXClosingFragment; children: JSXChild[]; } -export interface JSXIdentifier extends NodeBase { - type: 'JSXIdentifier'; +export interface JSXIdentifier extends BaseNode { + type: AST_NODE_TYPES.JSXIdentifier; name: string; } -export interface JSXMemberExpression extends NodeBase { - type: 'JSXMemberExpression'; +export interface JSXMemberExpression extends BaseNode { + type: AST_NODE_TYPES.JSXMemberExpression; name: string; } -export interface JSXOpeningElement extends NodeBase { - type: 'JSXOpeningElement'; +export interface JSXOpeningElement extends BaseNode { + type: AST_NODE_TYPES.JSXOpeningElement; typeParameters?: TSTypeParameterInstantiation; selfClosing: boolean; name: JSXTagNameExpression; attributes: JSXAttribute[]; } -export interface JSXOpeningFragment extends NodeBase { - type: 'JSXOpeningFragment'; +export interface JSXOpeningFragment extends BaseNode { + type: AST_NODE_TYPES.JSXOpeningFragment; } -export interface JSXSpreadAttribute extends NodeBase { - type: 'JSXSpreadAttribute'; +export interface JSXSpreadAttribute extends BaseNode { + type: AST_NODE_TYPES.JSXSpreadAttribute; argument: Expression; } -export interface JSXSpreadChild extends NodeBase { - type: 'JSXSpreadChild'; +export interface JSXSpreadChild extends BaseNode { + type: AST_NODE_TYPES.JSXSpreadChild; expression: Expression | JSXEmptyExpression; } -export interface JSXText extends NodeBase { - type: 'JSXText'; +export interface JSXText extends BaseNode { + type: AST_NODE_TYPES.JSXText; value: string; raw: string; } -export interface LabeledStatement extends NodeBase { - type: 'LabeledStatement'; +export interface LabeledStatement extends BaseNode { + type: AST_NODE_TYPES.LabeledStatement; label: Identifier; body: Statement; } export interface Literal extends LiteralBase { - type: 'Literal'; + type: AST_NODE_TYPES.Literal; } export interface LogicalExpression extends BinaryExpressionBase { - type: 'LogicalExpression'; + type: AST_NODE_TYPES.LogicalExpression; } -export interface MemberExpression extends NodeBase { - type: 'MemberExpression'; +export interface MemberExpression extends BaseNode { + type: AST_NODE_TYPES.MemberExpression; object: LeftHandSideExpression; property: Expression | Identifier; computed?: boolean; } -export interface MetaProperty extends NodeBase { - type: 'MetaProperty'; +export interface MetaProperty extends BaseNode { + type: AST_NODE_TYPES.MetaProperty; meta: Identifier; property: Identifier; } export interface MethodDefinition extends MethodDefinitionBase { - type: 'MethodDefinition'; + type: AST_NODE_TYPES.MethodDefinition; } -export interface NewExpression extends NodeBase { - type: 'NewExpression'; +export interface NewExpression extends BaseNode { + type: AST_NODE_TYPES.NewExpression; callee: LeftHandSideExpression; arguments: Expression[]; typeParameters?: TSTypeParameterInstantiation; } -export interface ObjectExpression extends NodeBase { - type: 'ObjectExpression'; +export interface ObjectExpression extends BaseNode { + type: AST_NODE_TYPES.ObjectExpression; properties: ObjectLiteralElementLike[]; } -export interface ObjectPattern extends NodeBase { - type: 'ObjectPattern'; +export interface ObjectPattern extends BaseNode { + type: AST_NODE_TYPES.ObjectPattern; properties: ObjectLiteralElementLike[]; typeAnnotation?: TSTypeAnnotation; optional?: boolean; } -export interface Program extends NodeBase { - type: 'Program'; +export interface Program extends BaseNode { + type: AST_NODE_TYPES.Program; body: Statement[]; - sourceType: 'module' | 'script'; + sourcetype: 'module' | 'script'; } -export interface Property extends NodeBase { - type: 'Property'; +export interface Property extends BaseNode { + type: AST_NODE_TYPES.Property; key: PropertyName; value: Expression | AssignmentPattern | BindingName; // TODO computed: boolean; @@ -853,53 +855,53 @@ export interface Property extends NodeBase { kind: 'init'; } -export interface RestElement extends NodeBase { - type: 'RestElement'; +export interface RestElement extends BaseNode { + type: AST_NODE_TYPES.RestElement; argument: BindingName | Expression | PropertyName; typeAnnotation?: TSTypeAnnotation; optional?: boolean; } -export interface ReturnStatement extends NodeBase { - type: 'ReturnStatement'; +export interface ReturnStatement extends BaseNode { + type: AST_NODE_TYPES.ReturnStatement; argument: Expression | null; } -export interface SequenceExpression extends NodeBase { - type: 'SequenceExpression'; +export interface SequenceExpression extends BaseNode { + type: AST_NODE_TYPES.SequenceExpression; expressions: Expression[]; } -export interface SpreadElement extends NodeBase { - type: 'SpreadElement'; +export interface SpreadElement extends BaseNode { + type: AST_NODE_TYPES.SpreadElement; argument: BindingName | Expression | PropertyName; } -export interface Super extends NodeBase { - type: 'Super'; +export interface Super extends BaseNode { + type: AST_NODE_TYPES.Super; } -export interface SwitchCase extends NodeBase { - type: 'SwitchCase'; +export interface SwitchCase extends BaseNode { + type: AST_NODE_TYPES.SwitchCase; test: Expression; consequent: Statement[]; } -export interface SwitchStatement extends NodeBase { - type: 'SwitchStatement'; +export interface SwitchStatement extends BaseNode { + type: AST_NODE_TYPES.SwitchStatement; discriminant: Expression; cases: SwitchCase[]; } -export interface TaggedTemplateExpression extends NodeBase { - type: 'TaggedTemplateExpression'; +export interface TaggedTemplateExpression extends BaseNode { + type: AST_NODE_TYPES.TaggedTemplateExpression; typeParameters: TSTypeParameterInstantiation; tag: LeftHandSideExpression; quasi: TemplateLiteral; } -export interface TemplateElement extends NodeBase { - type: 'TemplateElement'; +export interface TemplateElement extends BaseNode { + type: AST_NODE_TYPES.TemplateElement; value: { raw: string; cooked: string; @@ -907,97 +909,97 @@ export interface TemplateElement extends NodeBase { tail: boolean; } -export interface TemplateLiteral extends NodeBase { - type: 'TemplateLiteral'; +export interface TemplateLiteral extends BaseNode { + type: AST_NODE_TYPES.TemplateLiteral; quasis: TemplateElement[]; expressions: Expression[]; } -export interface ThisExpression extends NodeBase { - type: 'ThisExpression'; +export interface ThisExpression extends BaseNode { + type: AST_NODE_TYPES.ThisExpression; } -export interface ThrowStatement extends NodeBase { - type: 'ThrowStatement'; +export interface ThrowStatement extends BaseNode { + type: AST_NODE_TYPES.ThrowStatement; argument: Statement | null; } -export interface TryStatement extends NodeBase { - type: 'TryStatement'; +export interface TryStatement extends BaseNode { + type: AST_NODE_TYPES.TryStatement; block: BlockStatement; handler: CatchClause | null; finalizer: BlockStatement; } export interface TSAbstractClassProperty extends ClassPropertyBase { - type: 'TSAbstractClassProperty'; + type: AST_NODE_TYPES.TSAbstractClassProperty; } -export interface TSAbstractKeyword extends NodeBase { - type: 'TSAbstractKeyword'; +export interface TSAbstractKeyword extends BaseNode { + type: AST_NODE_TYPES.TSAbstractKeyword; } export interface TSAbstractMethodDefinition extends MethodDefinitionBase { - type: 'TSAbstractMethodDefinition'; + type: AST_NODE_TYPES.TSAbstractMethodDefinition; } -export interface TSAnyKeyword extends NodeBase { - type: 'TSAnyKeyword'; +export interface TSAnyKeyword extends BaseNode { + type: AST_NODE_TYPES.TSAnyKeyword; } -export interface TSArrayType extends NodeBase { - type: 'TSArrayType'; +export interface TSArrayType extends BaseNode { + type: AST_NODE_TYPES.TSArrayType; elementType: TypeNode; } -export interface TSAsExpression extends NodeBase { - type: 'TSAsExpression'; +export interface TSAsExpression extends BaseNode { + type: AST_NODE_TYPES.TSAsExpression; expression: Expression; typeAnnotation: TypeNode; } -export interface TSAsyncKeyword extends NodeBase { - type: 'TSAsyncKeyword'; +export interface TSAsyncKeyword extends BaseNode { + type: AST_NODE_TYPES.TSAsyncKeyword; } -export interface TSBigIntKeyword extends NodeBase { - type: 'TSBigIntKeyword'; +export interface TSBigIntKeyword extends BaseNode { + type: AST_NODE_TYPES.TSBigIntKeyword; } -export interface TSBooleanKeyword extends NodeBase { - type: 'TSBooleanKeyword'; +export interface TSBooleanKeyword extends BaseNode { + type: AST_NODE_TYPES.TSBooleanKeyword; } export interface TSCallSignatureDeclaration extends FunctionSignatureBase { - type: 'TSCallSignatureDeclaration'; + type: AST_NODE_TYPES.TSCallSignatureDeclaration; } export interface TSClassImplements extends TSHeritageBase { - type: 'TSClassImplements'; + type: AST_NODE_TYPES.TSClassImplements; } -export interface TSConditionalType extends NodeBase { - type: 'TSConditionalType'; +export interface TSConditionalType extends BaseNode { + type: AST_NODE_TYPES.TSConditionalType; checkType: TypeNode; extendsType: TypeNode; trueType: TypeNode; falseType: TypeNode; } -export interface TSConstKeyword extends NodeBase { - type: 'TSConstKeyword'; +export interface TSConstKeyword extends BaseNode { + type: AST_NODE_TYPES.TSConstKeyword; } export interface TSConstructorType extends FunctionSignatureBase { - type: 'TSConstructorType'; + type: AST_NODE_TYPES.TSConstructorType; } export interface TSConstructSignatureDeclaration extends FunctionSignatureBase { - type: 'TSConstructSignatureDeclaration'; + type: AST_NODE_TYPES.TSConstructSignatureDeclaration; } -export interface TSDeclareFunction extends NodeBase { - type: 'TSDeclareFunction'; +export interface TSDeclareFunction extends BaseNode { + type: AST_NODE_TYPES.TSDeclareFunction; id: Identifier | null; generator: boolean; expression: boolean; @@ -1009,16 +1011,16 @@ export interface TSDeclareFunction extends NodeBase { typeParameters?: TSTypeParameterDeclaration; } -export interface TSDeclareKeyword extends NodeBase { - type: 'TSDeclareKeyword'; +export interface TSDeclareKeyword extends BaseNode { + type: AST_NODE_TYPES.TSDeclareKeyword; } -export interface TSDefaultKeyword extends NodeBase { - type: 'TSDefaultKeyword'; +export interface TSDefaultKeyword extends BaseNode { + type: AST_NODE_TYPES.TSDefaultKeyword; } -export interface TSEnumDeclaration extends NodeBase { - type: 'TSEnumDeclaration'; +export interface TSEnumDeclaration extends BaseNode { + type: AST_NODE_TYPES.TSEnumDeclaration; id: Identifier; members: TSEnumMember[]; const?: boolean; @@ -1027,53 +1029,53 @@ export interface TSEnumDeclaration extends NodeBase { decorators?: Decorator[]; } -export interface TSEnumMember extends NodeBase { - type: 'TSEnumMember'; +export interface TSEnumMember extends BaseNode { + type: AST_NODE_TYPES.TSEnumMember; id: PropertyName; initializer?: Expression; } -export interface TSExportAssignment extends NodeBase { - type: 'TSExportAssignment'; +export interface TSExportAssignment extends BaseNode { + type: AST_NODE_TYPES.TSExportAssignment; expression: Expression; } -export interface TSExportKeyword extends NodeBase { - type: 'TSExportKeyword'; +export interface TSExportKeyword extends BaseNode { + type: AST_NODE_TYPES.TSExportKeyword; } -export interface TSExternalModuleReference extends NodeBase { - type: 'TSExternalModuleReference'; +export interface TSExternalModuleReference extends BaseNode { + type: AST_NODE_TYPES.TSExternalModuleReference; expression: Expression; } export interface TSFunctionType extends FunctionSignatureBase { - type: 'TSFunctionType'; + type: AST_NODE_TYPES.TSFunctionType; } -export interface TSImportEqualsDeclaration extends NodeBase { - type: 'TSImportEqualsDeclaration'; +export interface TSImportEqualsDeclaration extends BaseNode { + type: AST_NODE_TYPES.TSImportEqualsDeclaration; id: Identifier; moduleReference: EntityName | TSExternalModuleReference; isExport: boolean; } -export interface TSImportType extends NodeBase { - type: 'TSImportType'; +export interface TSImportType extends BaseNode { + type: AST_NODE_TYPES.TSImportType; isTypeOf: boolean; parameter: TypeNode; qualifier: EntityName | null; typeParameters: TSTypeParameterInstantiation | null; } -export interface TSIndexedAccessType extends NodeBase { - type: 'TSIndexedAccessType'; +export interface TSIndexedAccessType extends BaseNode { + type: AST_NODE_TYPES.TSIndexedAccessType; objectType: TypeNode; indexType: TypeNode; } -export interface TSIndexSignature extends NodeBase { - type: 'TSIndexSignature'; +export interface TSIndexSignature extends BaseNode { + type: AST_NODE_TYPES.TSIndexSignature; parameters: Parameter[]; typeAnnotation?: TSTypeAnnotation; readonly?: boolean; @@ -1082,13 +1084,13 @@ export interface TSIndexSignature extends NodeBase { static?: boolean; } -export interface TSInferType extends NodeBase { - type: 'TSInferType'; +export interface TSInferType extends BaseNode { + type: AST_NODE_TYPES.TSInferType; typeParameter: TSTypeParameterDeclaration; } -export interface TSInterfaceDeclaration extends NodeBase { - type: 'TSInterfaceDeclaration'; +export interface TSInterfaceDeclaration extends BaseNode { + type: AST_NODE_TYPES.TSInterfaceDeclaration; body: TSInterfaceBody; id: Identifier; typeParameters?: TSTypeParameterDeclaration; @@ -1099,35 +1101,35 @@ export interface TSInterfaceDeclaration extends NodeBase { declare?: boolean; } -export interface TSInterfaceBody extends NodeBase { - type: 'TSInterfaceBody'; +export interface TSInterfaceBody extends BaseNode { + type: AST_NODE_TYPES.TSInterfaceBody; body: TypeElement[]; } export interface TSInterfaceHeritage extends TSHeritageBase { - type: 'TSInterfaceHeritage'; + type: AST_NODE_TYPES.TSInterfaceHeritage; } -export interface TSIntersectionType extends NodeBase { - type: 'TSIntersectionType'; +export interface TSIntersectionType extends BaseNode { + type: AST_NODE_TYPES.TSIntersectionType; types: TypeNode[]; } -export interface TSLiteralType extends NodeBase { - type: 'TSLiteralType'; +export interface TSLiteralType extends BaseNode { + type: AST_NODE_TYPES.TSLiteralType; literal: LiteralExpression | UnaryExpression | UpdateExpression; } -export interface TSMappedType extends NodeBase { - type: 'TSMappedType'; +export interface TSMappedType extends BaseNode { + type: AST_NODE_TYPES.TSMappedType; typeParameter: TSTypeParameterDeclaration; readonly?: boolean | '-' | '+'; optional?: boolean | '-' | '+'; typeAnnotation?: TypeNode; } -export interface TSMethodSignature extends NodeBase { - type: 'TSMethodSignature'; +export interface TSMethodSignature extends BaseNode { + type: AST_NODE_TYPES.TSMethodSignature; computed: boolean; key: PropertyName; params: Parameter[]; @@ -1140,51 +1142,51 @@ export interface TSMethodSignature extends NodeBase { static?: boolean; } -export interface TSModuleBlock extends NodeBase { - type: 'TSModuleBlock'; +export interface TSModuleBlock extends BaseNode { + type: AST_NODE_TYPES.TSModuleBlock; body: Statement[]; } -export interface TSModuleDeclaration extends NodeBase { - type: 'TSModuleDeclaration'; +export interface TSModuleDeclaration extends BaseNode { + type: AST_NODE_TYPES.TSModuleDeclaration; id: Identifier | Literal; body?: TSModuleBlock | Identifier; global?: boolean; } -export interface TSNamespaceExportDeclaration extends NodeBase { - type: 'TSNamespaceExportDeclaration'; +export interface TSNamespaceExportDeclaration extends BaseNode { + type: AST_NODE_TYPES.TSNamespaceExportDeclaration; id: Identifier; } -export interface TSNeverKeyword extends NodeBase { - type: 'TSNeverKeyword'; +export interface TSNeverKeyword extends BaseNode { + type: AST_NODE_TYPES.TSNeverKeyword; } -export interface TSNonNullExpression extends NodeBase { - type: 'TSNonNullExpression'; +export interface TSNonNullExpression extends BaseNode { + type: AST_NODE_TYPES.TSNonNullExpression; expression: Expression; } -export interface TSNullKeyword extends NodeBase { - type: 'TSNullKeyword'; +export interface TSNullKeyword extends BaseNode { + type: AST_NODE_TYPES.TSNullKeyword; } -export interface TSNumberKeyword extends NodeBase { - type: 'TSNumberKeyword'; +export interface TSNumberKeyword extends BaseNode { + type: AST_NODE_TYPES.TSNumberKeyword; } -export interface TSObjectKeyword extends NodeBase { - type: 'TSObjectKeyword'; +export interface TSObjectKeyword extends BaseNode { + type: AST_NODE_TYPES.TSObjectKeyword; } -export interface TSOptionalType extends NodeBase { - type: 'TSOptionalType'; +export interface TSOptionalType extends BaseNode { + type: AST_NODE_TYPES.TSOptionalType; typeAnnotation: TypeNode; } -export interface TSParameterProperty extends NodeBase { - type: 'TSParameterProperty'; +export interface TSParameterProperty extends BaseNode { + type: AST_NODE_TYPES.TSParameterProperty; accessibility?: Accessibility; readonly?: boolean; static?: boolean; @@ -1192,13 +1194,13 @@ export interface TSParameterProperty extends NodeBase { parameter: AssignmentPattern | BindingName | RestElement; } -export interface TSParenthesizedType extends NodeBase { - type: 'TSParenthesizedType'; +export interface TSParenthesizedType extends BaseNode { + type: AST_NODE_TYPES.TSParenthesizedType; typeAnnotation: TypeNode; } -export interface TSPropertySignature extends NodeBase { - type: 'TSPropertySignature'; +export interface TSPropertySignature extends BaseNode { + type: AST_NODE_TYPES.TSPropertySignature; optional?: boolean; computed: boolean; key: PropertyName; @@ -1210,171 +1212,171 @@ export interface TSPropertySignature extends NodeBase { accessability?: Accessibility; } -export interface TSPublicKeyword extends NodeBase { - type: 'TSPublicKeyword'; +export interface TSPublicKeyword extends BaseNode { + type: AST_NODE_TYPES.TSPublicKeyword; } -export interface TSPrivateKeyword extends NodeBase { - type: 'TSPrivateKeyword'; +export interface TSPrivateKeyword extends BaseNode { + type: AST_NODE_TYPES.TSPrivateKeyword; } -export interface TSProtectedKeyword extends NodeBase { - type: 'TSProtectedKeyword'; +export interface TSProtectedKeyword extends BaseNode { + type: AST_NODE_TYPES.TSProtectedKeyword; } -export interface TSQualifiedName extends NodeBase { - type: 'TSQualifiedName'; +export interface TSQualifiedName extends BaseNode { + type: AST_NODE_TYPES.TSQualifiedName; left: EntityName; right: Identifier; } -export interface TSReadonlyKeyword extends NodeBase { - type: 'TSReadonlyKeyword'; +export interface TSReadonlyKeyword extends BaseNode { + type: AST_NODE_TYPES.TSReadonlyKeyword; } -export interface TSRestType extends NodeBase { - type: 'TSRestType'; +export interface TSRestType extends BaseNode { + type: AST_NODE_TYPES.TSRestType; typeAnnotation: TypeNode; } -export interface TSStaticKeyword extends NodeBase { - type: 'TSStaticKeyword'; +export interface TSStaticKeyword extends BaseNode { + type: AST_NODE_TYPES.TSStaticKeyword; } -export interface TSStringKeyword extends NodeBase { - type: 'TSStringKeyword'; +export interface TSStringKeyword extends BaseNode { + type: AST_NODE_TYPES.TSStringKeyword; } -export interface TSSymbolKeyword extends NodeBase { - type: 'TSSymbolKeyword'; +export interface TSSymbolKeyword extends BaseNode { + type: AST_NODE_TYPES.TSSymbolKeyword; } -export interface TSThisType extends NodeBase { - type: 'TSThisType'; +export interface TSThisType extends BaseNode { + type: AST_NODE_TYPES.TSThisType; } -export interface TSTupleType extends NodeBase { - type: 'TSTupleType'; +export interface TSTupleType extends BaseNode { + type: AST_NODE_TYPES.TSTupleType; elementTypes: TypeNode[]; } -export interface TSTypeAliasDeclaration extends NodeBase { - type: 'TSTypeAliasDeclaration'; +export interface TSTypeAliasDeclaration extends BaseNode { + type: AST_NODE_TYPES.TSTypeAliasDeclaration; id: Identifier; typeAnnotation: TypeNode; declare?: boolean; typeParameters?: TSTypeParameterDeclaration; } -export interface TSTypeAnnotation extends NodeBase { - type: 'TSTypeAnnotation'; +export interface TSTypeAnnotation extends BaseNode { + type: AST_NODE_TYPES.TSTypeAnnotation; typeAnnotation: TypeNode; } -export interface TSTypeAssertion extends NodeBase { - type: 'TSTypeAssertion'; +export interface TSTypeAssertion extends BaseNode { + type: AST_NODE_TYPES.TSTypeAssertion; typeAnnotation: TypeNode; expression: UnaryExpression; } -export interface TSTypeLiteral extends NodeBase { - type: 'TSTypeLiteral'; +export interface TSTypeLiteral extends BaseNode { + type: AST_NODE_TYPES.TSTypeLiteral; members: TypeElement[]; } -export interface TSTypeOperator extends NodeBase { - type: 'TSTypeOperator'; +export interface TSTypeOperator extends BaseNode { + type: AST_NODE_TYPES.TSTypeOperator; operator: 'keyof' | 'unique'; typeAnnotation?: TSTypeAnnotation; } -export interface TSTypeParameter extends NodeBase { - type: 'TSTypeParameter'; +export interface TSTypeParameter extends BaseNode { + type: AST_NODE_TYPES.TSTypeParameter; name: Identifier; constraint?: TypeNode; default?: TypeNode; } -export interface TSTypeParameterDeclaration extends NodeBase { - type: 'TSTypeParameterDeclaration'; +export interface TSTypeParameterDeclaration extends BaseNode { + type: AST_NODE_TYPES.TSTypeParameterDeclaration; params: TSTypeParameter[]; } -export interface TSTypeParameterInstantiation extends NodeBase { - type: 'TSTypeParameterInstantiation'; +export interface TSTypeParameterInstantiation extends BaseNode { + type: AST_NODE_TYPES.TSTypeParameterInstantiation; params: TypeNode[]; } -export interface TSTypePredicate extends NodeBase { - type: 'TSTypePredicate'; +export interface TSTypePredicate extends BaseNode { + type: AST_NODE_TYPES.TSTypePredicate; parameterName: Identifier | TSThisType; typeAnnotation: TypeNode; } -export interface TSTypeQuery extends NodeBase { - type: 'TSTypeQuery'; +export interface TSTypeQuery extends BaseNode { + type: AST_NODE_TYPES.TSTypeQuery; exprName: EntityName; } -export interface TSTypeReference extends NodeBase { - type: 'TSTypeReference'; +export interface TSTypeReference extends BaseNode { + type: AST_NODE_TYPES.TSTypeReference; typeName: EntityName; typeParameters?: TSTypeParameterInstantiation; } -export interface TSUndefinedKeyword extends NodeBase { - type: 'TSUndefinedKeyword'; +export interface TSUndefinedKeyword extends BaseNode { + type: AST_NODE_TYPES.TSUndefinedKeyword; } -export interface TSUnionType extends NodeBase { - type: 'TSUnionType'; +export interface TSUnionType extends BaseNode { + type: AST_NODE_TYPES.TSUnionType; types: TypeNode[]; } -export interface TSUnknownKeyword extends NodeBase { - type: 'TSUnknownKeyword'; +export interface TSUnknownKeyword extends BaseNode { + type: AST_NODE_TYPES.TSUnknownKeyword; } -export interface TSVoidKeyword extends NodeBase { - type: 'TSVoidKeyword'; +export interface TSVoidKeyword extends BaseNode { + type: AST_NODE_TYPES.TSVoidKeyword; } export interface UpdateExpression extends UnaryExpressionBase { - type: 'UpdateExpression'; + type: AST_NODE_TYPES.UpdateExpression; } export interface UnaryExpression extends UnaryExpressionBase { - type: 'UnaryExpression'; + type: AST_NODE_TYPES.UnaryExpression; } -export interface VariableDeclaration extends NodeBase { - type: 'VariableDeclaration'; +export interface VariableDeclaration extends BaseNode { + type: AST_NODE_TYPES.VariableDeclaration; declarations: VariableDeclarator[]; kind: 'let' | 'const' | 'var'; declare?: boolean; } -export interface VariableDeclarator extends NodeBase { - type: 'VariableDeclarator'; +export interface VariableDeclarator extends BaseNode { + type: AST_NODE_TYPES.VariableDeclarator; id: BindingName; init: Expression | null; definite?: boolean; } -export interface WhileStatement extends NodeBase { - type: 'WhileStatement'; +export interface WhileStatement extends BaseNode { + type: AST_NODE_TYPES.WhileStatement; test: Expression; body: Statement; } -export interface WithStatement extends NodeBase { - type: 'WithStatement'; +export interface WithStatement extends BaseNode { + type: AST_NODE_TYPES.WithStatement; object: Expression; body: Statement; } -export interface YieldExpression extends NodeBase { - type: 'YieldExpression'; +export interface YieldExpression extends BaseNode { + type: AST_NODE_TYPES.YieldExpression; delegate: boolean; argument?: Expression; } From f991152b88e8df89bf54f3f511ff33a77e44fd16 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Fri, 1 Feb 2019 18:00:04 -0800 Subject: [PATCH 43/92] review fixes 2/2 --- packages/eslint-plugin/typings/ts-eslint.d.ts | 2 +- packages/typescript-estree/src/typedefs.ts | 78 +++++++++++++------ 2 files changed, 54 insertions(+), 26 deletions(-) diff --git a/packages/eslint-plugin/typings/ts-eslint.d.ts b/packages/eslint-plugin/typings/ts-eslint.d.ts index 808bb9096678..7a0d03a2c5cf 100644 --- a/packages/eslint-plugin/typings/ts-eslint.d.ts +++ b/packages/eslint-plugin/typings/ts-eslint.d.ts @@ -314,7 +314,7 @@ declare module 'ts-eslint' { /** * An override of the location of the report */ - loc?: TSESTree.NodeLocation; + loc?: TSESTree.SourceLocation; } interface RuleContext { diff --git a/packages/typescript-estree/src/typedefs.ts b/packages/typescript-estree/src/typedefs.ts index f52fa9e221f6..d41a9d431300 100644 --- a/packages/typescript-estree/src/typedefs.ts +++ b/packages/typescript-estree/src/typedefs.ts @@ -44,6 +44,41 @@ interface BaseNode { // source?: string | null; } +/* + * Token and Comment are pseudo-nodes to represent pieces of source code + * + * NOTE: + * They are not included in the `Node` union below on purpose because they + * are not ever included as part of the standard AST tree. + */ + +export interface Token extends BaseNode { + type: + | 'Boolean' + | 'Identifier' + | 'JSXIdentifier' + | 'JSXMemberExpression' + | 'JSXText' + | 'Keyword' + | 'Null' + | 'Numeric' + | 'Punctuator' + | 'RegularExpression' + | 'String' + | 'Template'; + value: string; + regex?: { + pattern: string; + flags: string; + }; +} +export interface Comment extends BaseNode { + type: 'Line' | 'Block'; + value: string; +} + +// Every single valid AST Node +// Please keep it sorted alphabetically. export type Node = | ArrayExpression | ArrayPattern @@ -445,6 +480,7 @@ interface FunctionDeclarationBase extends BaseNode { body?: BlockStatement | null; returnType?: TSTypeAnnotation; typeParameters?: TSTypeParameterDeclaration; + declare?: boolean; } interface FunctionSignatureBase extends BaseNode { @@ -454,8 +490,8 @@ interface FunctionSignatureBase extends BaseNode { } interface LiteralBase extends BaseNode { - raw: boolean | number | RegExp | string | null; - value: string; + raw: string; + value: boolean | number | RegExp | string | null; regex?: { pattern: string; flags: string; @@ -475,7 +511,7 @@ interface MethodDefinitionBase extends BaseNode { interface TSHeritageBase extends BaseNode { expression: Expression; - typeParameters?: TSTypeParameterDeclaration; + typeParameters?: TSTypeParameterInstantiation; } interface UnaryExpressionBase extends BaseNode { @@ -509,8 +545,8 @@ export interface ArrowFunctionExpression extends BaseNode { body: Expression | BlockStatement; async: boolean; expression: boolean; - returnType: TSTypeAnnotation; - typeParameters: TSTypeParameterDeclaration; + returnType?: TSTypeAnnotation; + typeParameters?: TSTypeParameterDeclaration; } export interface AssignmentExpression extends BinaryExpressionBase { @@ -578,11 +614,6 @@ export interface ClassProperty extends ClassPropertyBase { type: AST_NODE_TYPES.ClassProperty; } -export interface Comment extends BaseNode { - type: 'Line' | 'Block'; - value: string; -} - export interface ConditionalExpression extends BaseNode { type: AST_NODE_TYPES.ConditionalExpression; test: Expression; @@ -843,16 +874,19 @@ export interface Program extends BaseNode { type: AST_NODE_TYPES.Program; body: Statement[]; sourcetype: 'module' | 'script'; + comments?: Comment[]; + tokens?: Token[]; } export interface Property extends BaseNode { type: AST_NODE_TYPES.Property; key: PropertyName; - value: Expression | AssignmentPattern | BindingName; // TODO + value: Expression | AssignmentPattern | BindingName; computed: boolean; method: boolean; shorthand: boolean; kind: 'init'; + typeParameters?: TSTypeParameterDeclaration; } export interface RestElement extends BaseNode { @@ -860,6 +894,7 @@ export interface RestElement extends BaseNode { argument: BindingName | Expression | PropertyName; typeAnnotation?: TSTypeAnnotation; optional?: boolean; + value?: AssignmentPattern; } export interface ReturnStatement extends BaseNode { @@ -895,7 +930,7 @@ export interface SwitchStatement extends BaseNode { export interface TaggedTemplateExpression extends BaseNode { type: AST_NODE_TYPES.TaggedTemplateExpression; - typeParameters: TSTypeParameterInstantiation; + typeParameters?: TSTypeParameterInstantiation; tag: LeftHandSideExpression; quasi: TemplateLiteral; } @@ -998,17 +1033,8 @@ export interface TSConstructSignatureDeclaration extends FunctionSignatureBase { type: AST_NODE_TYPES.TSConstructSignatureDeclaration; } -export interface TSDeclareFunction extends BaseNode { +export interface TSDeclareFunction extends FunctionDeclarationBase { type: AST_NODE_TYPES.TSDeclareFunction; - id: Identifier | null; - generator: boolean; - expression: boolean; - async: boolean; - params: Parameter[]; - body?: BlockStatement | null; - returnType?: TSTypeAnnotation; - declare: boolean; - typeParameters?: TSTypeParameterDeclaration; } export interface TSDeclareKeyword extends BaseNode { @@ -1134,7 +1160,7 @@ export interface TSMethodSignature extends BaseNode { key: PropertyName; params: Parameter[]; optional?: boolean; - returnType?: TypeNode; + returnType?: TSTypeAnnotation; readonly?: boolean; typeParameters?: TSTypeParameterDeclaration; accessibility?: Accessibility; @@ -1152,6 +1178,8 @@ export interface TSModuleDeclaration extends BaseNode { id: Identifier | Literal; body?: TSModuleBlock | Identifier; global?: boolean; + declare?: boolean; + modifiers?: Modifier[]; } export interface TSNamespaceExportDeclaration extends BaseNode { @@ -1209,7 +1237,7 @@ export interface TSPropertySignature extends BaseNode { readonly?: boolean; static?: boolean; export?: boolean; - accessability?: Accessibility; + accessibility?: Accessibility; } export interface TSPublicKeyword extends BaseNode { @@ -1310,7 +1338,7 @@ export interface TSTypeParameterInstantiation extends BaseNode { export interface TSTypePredicate extends BaseNode { type: AST_NODE_TYPES.TSTypePredicate; parameterName: Identifier | TSThisType; - typeAnnotation: TypeNode; + typeAnnotation: TSTypeAnnotation; } export interface TSTypeQuery extends BaseNode { From db338a314d6b1b3d647b66ba2648f30638cd2785 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Sun, 3 Feb 2019 18:00:30 -0800 Subject: [PATCH 44/92] member-naming --- .../eslint-plugin/src/rules/member-naming.ts | 40 ++++--- packages/eslint-plugin/src/tsestree-utils.ts | 6 +- .../tests/rules/member-naming.test.ts | 112 +++++++++++++++--- 3 files changed, 123 insertions(+), 35 deletions(-) diff --git a/packages/eslint-plugin/src/rules/member-naming.ts b/packages/eslint-plugin/src/rules/member-naming.ts index 2436c56eee6c..52a0cd40ed70 100644 --- a/packages/eslint-plugin/src/rules/member-naming.ts +++ b/packages/eslint-plugin/src/rules/member-naming.ts @@ -3,32 +3,40 @@ * @author Ian MacLeod */ +import { TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; +import { getNameFromPropertyName } from '../tsestree-utils'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -interface Options { +interface Config { private?: T; protected?: T; public?: T; } -type Modifiers = keyof Options; +type Modifiers = keyof Config; +type Options = [Config]; +type MessageIds = 'incorrectName'; -const defaultOptions: Options[] = [{}]; +const defaultOptions: Options = [{}]; -const rule: RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { description: 'Enforces naming conventions for class members by visibility.', - category: 'TypeScript', + category: 'Stylistic Issues', url: util.metaDocsUrl('member-naming'), recommended: false }, + messages: { + incorrectName: + '{{accessibility}} property {{name}} should match {{convention}}.' + }, schema: [ { type: 'object', @@ -57,14 +65,13 @@ const rule: RuleModule = { create(context) { const config = util.applyDefault(defaultOptions, context.options)[0]; - const conventions = (Object.keys(config) as Modifiers[]).reduce>( - (acc, accessibility) => { - acc[accessibility] = new RegExp(config[accessibility]!); + const conventions = (Object.keys(config) as Modifiers[]).reduce< + Config + >((acc, accessibility) => { + acc[accessibility] = new RegExp(config[accessibility]!); - return acc; - }, - {} - ); + return acc; + }, {}); //---------------------------------------------------------------------- // Helpers @@ -77,8 +84,10 @@ const rule: RuleModule = { * @returns {void} * @private */ - function validateName(node): void { - const name = node.key.name; + function validateName( + node: TSESTree.MethodDefinition | TSESTree.ClassProperty + ): void { + const name = getNameFromPropertyName(node.key); const accessibility: Modifiers = node.accessibility || 'public'; const convention = conventions[accessibility]; @@ -86,8 +95,7 @@ const rule: RuleModule = { context.report({ node: node.key, - message: - '{{accessibility}} property {{name}} should match {{convention}}.', + messageId: 'incorrectName', data: { accessibility, name, convention } }); } diff --git a/packages/eslint-plugin/src/tsestree-utils.ts b/packages/eslint-plugin/src/tsestree-utils.ts index badf63597385..f180598a8995 100644 --- a/packages/eslint-plugin/src/tsestree-utils.ts +++ b/packages/eslint-plugin/src/tsestree-utils.ts @@ -2,16 +2,16 @@ * @fileoverview Utilities for working with union types exported by the TSESTree types */ -import { TSESTree } from '@typescript-eslint/typescript-estree'; +import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; export function getNameFromPropertyName( propertyName: TSESTree.PropertyName ): string { - if (propertyName.type === 'Identifier') { + if (propertyName.type === AST_NODE_TYPES.Identifier) { return propertyName.name; } - return propertyName.value; + return `${propertyName.value}`; } export type InferOptionsTypeFromRule = T extends RuleModule< diff --git a/packages/eslint-plugin/tests/rules/member-naming.test.ts b/packages/eslint-plugin/tests/rules/member-naming.test.ts index aefe3eb4a469..2bab2df33c07 100644 --- a/packages/eslint-plugin/tests/rules/member-naming.test.ts +++ b/packages/eslint-plugin/tests/rules/member-naming.test.ts @@ -98,7 +98,12 @@ class Class { options: [{ public: '^_' }], errors: [ { - message: 'public property fooBar should match /^_/.', + messageId: 'incorrectName', + data: { + accessibility: 'public', + convention: '/^_/', + name: 'fooBar' + }, line: 1, column: 15 } @@ -109,7 +114,12 @@ class Class { options: [{ public: '^_' }], errors: [ { - message: 'public property fooBar should match /^_/.', + messageId: 'incorrectName', + data: { + accessibility: 'public', + convention: '/^_/', + name: 'fooBar' + }, line: 1, column: 22 } @@ -120,7 +130,12 @@ class Class { options: [{ protected: '^_' }], errors: [ { - message: 'protected property fooBar should match /^_/.', + messageId: 'incorrectName', + data: { + accessibility: 'protected', + convention: '/^_/', + name: 'fooBar' + }, line: 1, column: 25 } @@ -131,7 +146,12 @@ class Class { options: [{ private: '^_' }], errors: [ { - message: 'private property fooBar should match /^_/.', + messageId: 'incorrectName', + data: { + accessibility: 'private', + convention: '/^_/', + name: 'fooBar' + }, line: 1, column: 23 } @@ -155,22 +175,42 @@ class Class { ], errors: [ { - message: 'public property one should match /^pub[A-Z]/.', + messageId: 'incorrectName', + data: { + accessibility: 'public', + convention: '/^pub[A-Z]/', + name: 'one' + }, line: 3, column: 5 }, { - message: 'public property two should match /^pub[A-Z]/.', + messageId: 'incorrectName', + data: { + accessibility: 'public', + convention: '/^pub[A-Z]/', + name: 'two' + }, line: 4, column: 12 }, { - message: 'protected property three should match /^prot[A-Z]/.', + messageId: 'incorrectName', + data: { + accessibility: 'protected', + convention: '/^prot[A-Z]/', + name: 'three' + }, line: 5, column: 15 }, { - message: 'private property four should match /^priv[A-Z]/.', + messageId: 'incorrectName', + data: { + accessibility: 'private', + convention: '/^priv[A-Z]/', + name: 'four' + }, line: 6, column: 13 } @@ -194,22 +234,42 @@ class Class { ], errors: [ { - message: 'public property one should match /^pub[A-Z]/.', + messageId: 'incorrectName', + data: { + accessibility: 'public', + convention: '/^pub[A-Z]/', + name: 'one' + }, line: 3, column: 5 }, { - message: 'public property two should match /^pub[A-Z]/.', + messageId: 'incorrectName', + data: { + accessibility: 'public', + convention: '/^pub[A-Z]/', + name: 'two' + }, line: 4, column: 12 }, { - message: 'protected property three should match /^prot[A-Z]/.', + messageId: 'incorrectName', + data: { + accessibility: 'protected', + convention: '/^prot[A-Z]/', + name: 'three' + }, line: 5, column: 15 }, { - message: 'private property four should match /^priv[A-Z]/.', + messageId: 'incorrectName', + data: { + accessibility: 'private', + convention: '/^priv[A-Z]/', + name: 'four' + }, line: 6, column: 13 } @@ -233,22 +293,42 @@ class Class { ], errors: [ { - message: 'public property one should match /^pub[A-Z]/.', + messageId: 'incorrectName', + data: { + accessibility: 'public', + convention: '/^pub[A-Z]/', + name: 'one' + }, line: 3, column: 5 }, { - message: 'public property two should match /^pub[A-Z]/.', + messageId: 'incorrectName', + data: { + accessibility: 'public', + convention: '/^pub[A-Z]/', + name: 'two' + }, line: 4, column: 12 }, { - message: 'protected property three should match /^prot[A-Z]/.', + messageId: 'incorrectName', + data: { + accessibility: 'protected', + convention: '/^prot[A-Z]/', + name: 'three' + }, line: 5, column: 15 }, { - message: 'private property four should match /^priv[A-Z]/.', + messageId: 'incorrectName', + data: { + accessibility: 'private', + convention: '/^priv[A-Z]/', + name: 'four' + }, line: 6, column: 13 } From be34387d8813c621f1de7b840f91b63cc7c45825 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Sun, 3 Feb 2019 19:00:36 -0800 Subject: [PATCH 45/92] member-ordering --- .../src/rules/member-ordering.ts | 119 +-- .../tests/rules/member-ordering.test.ts | 802 ++++++++++++++---- 2 files changed, 690 insertions(+), 231 deletions(-) diff --git a/packages/eslint-plugin/src/rules/member-ordering.ts b/packages/eslint-plugin/src/rules/member-ordering.ts index fa5a30316599..2b339e2e1874 100644 --- a/packages/eslint-plugin/src/rules/member-ordering.ts +++ b/packages/eslint-plugin/src/rules/member-ordering.ts @@ -3,13 +3,27 @@ * @author Patricio Trevino */ +import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; +import { getNameFromPropertyName } from '../tsestree-utils'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ +export type MessageIds = 'incorrectOrder'; +type OrderConfig = string[] | 'never'; +export type Options = [ + { + default?: OrderConfig; + classes?: OrderConfig; + classExpressions?: OrderConfig; + interfaces?: OrderConfig; + typeLiterals?: OrderConfig; + } +]; + const schemaOptions = ['field', 'method', 'constructor'].reduce( (options, type) => { options.push(type); @@ -31,16 +45,7 @@ const schemaOptions = ['field', 'method', 'constructor'].reduce( [] ); -type OrderConfig = string[] | 'never'; -interface Options { - default: OrderConfig; - classes?: OrderConfig; - classExpressions?: OrderConfig; - interfaces?: OrderConfig; - typeLiterals?: OrderConfig; -} - -const defaultOptions: Options[] = [ +const defaultOptions: Options = [ { default: [ 'public-static-field', @@ -82,16 +87,20 @@ const defaultOptions: Options[] = [ } ]; -const rule: RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { description: 'Require a consistent member declaration order', extraDescription: [util.tslintRule('member-ordering')], - category: 'TypeScript', + category: 'Stylistic Issues', url: util.metaDocsUrl('member-ordering'), recommended: false }, + messages: { + incorrectOrder: + 'Member {{name}} should be declared before all {{rank}} definitions.' + }, schema: [ { type: 'object', @@ -179,31 +188,27 @@ const rule: RuleModule = { // Helpers //---------------------------------------------------------------------- - /** - * Determines if `node` should be processed as a method instead of a field. - * @param {ASTNode} node the node to be inspected. - */ - function shouldBeProcessedAsMethod(node): boolean { - // check for bound methods in ClassProperty nodes. - return node.value && functionExpressions.indexOf(node.value.type) > -1; - } - /** * Gets the node type. - * @param {ASTNode} node the node to be evaluated. + * @param node the node to be evaluated. */ - function getNodeType(node): string | null { + function getNodeType( + node: TSESTree.ClassElement | TSESTree.TypeElement + ): string | null { // TODO: add missing TSCallSignatureDeclaration switch (node.type) { - case 'MethodDefinition': + case AST_NODE_TYPES.MethodDefinition: return node.kind; - case 'TSMethodSignature': + case AST_NODE_TYPES.TSMethodSignature: return 'method'; - case 'TSConstructSignatureDeclaration': + case AST_NODE_TYPES.TSConstructSignatureDeclaration: return 'constructor'; - case 'ClassProperty': - case 'TSPropertySignature': - return shouldBeProcessedAsMethod(node) ? 'method' : 'field'; + case AST_NODE_TYPES.ClassProperty: + return node.value && functionExpressions.indexOf(node.value.type) > -1 + ? 'method' + : 'field'; + case AST_NODE_TYPES.TSPropertySignature: + return 'field'; default: return null; } @@ -211,17 +216,21 @@ const rule: RuleModule = { /** * Gets the member name based on the member type. - * @param {ASTNode} node the node to be evaluated. + * @param node the node to be evaluated. */ - function getMemberName(node): string | null { + function getMemberName( + node: TSESTree.ClassElement | TSESTree.TypeElement + ): string | null { switch (node.type) { - case 'ClassProperty': - case 'MethodDefinition': - return node.kind === 'constructor' ? 'constructor' : node.key.name; - case 'TSPropertySignature': - case 'TSMethodSignature': - return node.key.name; - case 'TSConstructSignatureDeclaration': + case AST_NODE_TYPES.TSPropertySignature: + case AST_NODE_TYPES.TSMethodSignature: + case AST_NODE_TYPES.ClassProperty: + return getNameFromPropertyName(node.key); + case AST_NODE_TYPES.MethodDefinition: + return node.kind === 'constructor' + ? 'constructor' + : getNameFromPropertyName(node.key); + case AST_NODE_TYPES.TSConstructSignatureDeclaration: return 'new'; default: return null; @@ -251,12 +260,12 @@ const rule: RuleModule = { /** * Gets the rank of the node given the order. - * @param {ASTNode} node the node to be evaluated. + * @param node the node to be evaluated. * @param order the current order to be validated. * @param supportsModifiers a flag indicating whether the type supports modifiers or not. */ function getRank( - node, + node: TSESTree.ClassElement | TSESTree.TypeElement, order: string[], supportsModifiers: boolean ): number { @@ -266,8 +275,11 @@ const rule: RuleModule = { return Number.MAX_SAFE_INTEGER; } - const scope = node.static ? 'static' : 'instance'; - const accessibility = node.accessibility || 'public'; + const scope = 'static' in node && node.static ? 'static' : 'instance'; + const accessibility = + 'accessibility' in node && node.accessibility + ? node.accessibility + : 'public'; const names = []; @@ -321,12 +333,12 @@ const rule: RuleModule = { /** * Validates each member rank. - * @param {Array} members the members to be validated. + * @param members the members to be validated. * @param order the current order to be validated. * @param supportsModifiers a flag indicating whether the type supports modifiers or not. */ function validateMembers( - members, + members: (TSESTree.ClassElement | TSESTree.TypeElement)[], order: OrderConfig, supportsModifiers: boolean ): void { @@ -340,8 +352,7 @@ const rule: RuleModule = { if (rank < previousRanks[previousRanks.length - 1]) { context.report({ node: member, - message: - 'Member {{name}} should be declared before all {{rank}} definitions.', + messageId: 'incorrectOrder', data: { name: getMemberName(member), rank: getLowestRank(previousRanks, rank, order) @@ -359,31 +370,31 @@ const rule: RuleModule = { // Public //---------------------------------------------------------------------- return { - ClassDeclaration(node) { + ClassDeclaration(node: TSESTree.ClassDeclaration) { validateMembers( node.body.body, - options.classes || options.default, + options.classes || options.default!, true ); }, - ClassExpression(node) { + ClassExpression(node: TSESTree.ClassExpression) { validateMembers( node.body.body, - options.classExpressions || options.default, + options.classExpressions || options.default!, true ); }, - TSInterfaceDeclaration(node) { + TSInterfaceDeclaration(node: TSESTree.TSInterfaceDeclaration) { validateMembers( node.body.body, - options.interfaces || options.default, + options.interfaces || options.default!, false ); }, - TSTypeLiteral(node) { + TSTypeLiteral(node: TSESTree.TSTypeLiteral) { validateMembers( node.members, - options.typeLiterals || options.default, + options.typeLiterals || options.default!, false ); } diff --git a/packages/eslint-plugin/tests/rules/member-ordering.test.ts b/packages/eslint-plugin/tests/rules/member-ordering.test.ts index d6e9f85d3218..e5c5962af693 100644 --- a/packages/eslint-plugin/tests/rules/member-ordering.test.ts +++ b/packages/eslint-plugin/tests/rules/member-ordering.test.ts @@ -1244,8 +1244,11 @@ interface Foo { `, errors: [ { - message: - 'Member new should be declared before all method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'new', + rank: 'method' + }, line: 16, column: 5 } @@ -1273,38 +1276,65 @@ interface Foo { options: [{ default: ['method', 'constructor', 'field'] }], errors: [ { - message: 'Member G should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'G', + rank: 'field' + }, line: 10, column: 5 }, { - message: 'Member H should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'H', + rank: 'field' + }, line: 11, column: 5 }, { - message: 'Member I should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'I', + rank: 'field' + }, line: 12, column: 5 }, { - message: 'Member J should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'J', + rank: 'field' + }, line: 13, column: 5 }, { - message: 'Member K should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'K', + rank: 'field' + }, line: 14, column: 5 }, { - message: 'Member L should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'L', + rank: 'field' + }, line: 15, column: 5 }, { - message: - 'Member new should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'new', + rank: 'field' + }, line: 16, column: 5 } @@ -1332,38 +1362,65 @@ interface Foo { options: [{ interfaces: ['method', 'constructor', 'field'] }], errors: [ { - message: 'Member G should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'G', + rank: 'field' + }, line: 10, column: 5 }, { - message: 'Member H should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'H', + rank: 'field' + }, line: 11, column: 5 }, { - message: 'Member I should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'I', + rank: 'field' + }, line: 12, column: 5 }, { - message: 'Member J should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'J', + rank: 'field' + }, line: 13, column: 5 }, { - message: 'Member K should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'K', + rank: 'field' + }, line: 14, column: 5 }, { - message: 'Member L should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'L', + rank: 'field' + }, line: 15, column: 5 }, { - message: - 'Member new should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'new', + rank: 'field' + }, line: 16, column: 5 } @@ -1396,38 +1453,65 @@ interface Foo { ], errors: [ { - message: 'Member G should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'G', + rank: 'field' + }, line: 10, column: 5 }, { - message: 'Member H should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'H', + rank: 'field' + }, line: 11, column: 5 }, { - message: 'Member I should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'I', + rank: 'field' + }, line: 12, column: 5 }, { - message: 'Member J should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'J', + rank: 'field' + }, line: 13, column: 5 }, { - message: 'Member K should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'K', + rank: 'field' + }, line: 14, column: 5 }, { - message: 'Member L should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'L', + rank: 'field' + }, line: 15, column: 5 }, { - message: - 'Member new should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'new', + rank: 'field' + }, line: 16, column: 5 } @@ -1459,27 +1543,47 @@ interface Foo { ], errors: [ { - message: 'Member B should be declared before all method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'B', + rank: 'method' + }, line: 7, column: 5 }, { - message: 'Member C should be declared before all method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'C', + rank: 'method' + }, line: 9, column: 5 }, { - message: 'Member D should be declared before all method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'D', + rank: 'method' + }, line: 11, column: 5 }, { - message: 'Member E should be declared before all method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'E', + rank: 'method' + }, line: 13, column: 5 }, { - message: 'Member F should be declared before all method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'F', + rank: 'method' + }, line: 15, column: 5 } @@ -1506,8 +1610,11 @@ type Foo = { `, errors: [ { - message: - 'Member new should be declared before all method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'new', + rank: 'method' + }, line: 16, column: 5 } @@ -1535,38 +1642,65 @@ type Foo = { options: [{ default: ['method', 'constructor', 'field'] }], errors: [ { - message: 'Member G should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'G', + rank: 'field' + }, line: 10, column: 5 }, { - message: 'Member H should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'H', + rank: 'field' + }, line: 11, column: 5 }, { - message: 'Member I should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'I', + rank: 'field' + }, line: 12, column: 5 }, { - message: 'Member J should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'J', + rank: 'field' + }, line: 13, column: 5 }, { - message: 'Member K should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'K', + rank: 'field' + }, line: 14, column: 5 }, { - message: 'Member L should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'L', + rank: 'field' + }, line: 15, column: 5 }, { - message: - 'Member new should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'new', + rank: 'field' + }, line: 16, column: 5 } @@ -1594,38 +1728,65 @@ type Foo = { options: [{ typeLiterals: ['method', 'constructor', 'field'] }], errors: [ { - message: 'Member G should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'G', + rank: 'field' + }, line: 10, column: 5 }, { - message: 'Member H should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'H', + rank: 'field' + }, line: 11, column: 5 }, { - message: 'Member I should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'I', + rank: 'field' + }, line: 12, column: 5 }, { - message: 'Member J should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'J', + rank: 'field' + }, line: 13, column: 5 }, { - message: 'Member K should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'K', + rank: 'field' + }, line: 14, column: 5 }, { - message: 'Member L should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'L', + rank: 'field' + }, line: 15, column: 5 }, { - message: - 'Member new should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'new', + rank: 'field' + }, line: 16, column: 5 } @@ -1658,38 +1819,65 @@ type Foo = { ], errors: [ { - message: 'Member G should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'G', + rank: 'field' + }, line: 10, column: 5 }, { - message: 'Member H should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'H', + rank: 'field' + }, line: 11, column: 5 }, { - message: 'Member I should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'I', + rank: 'field' + }, line: 12, column: 5 }, { - message: 'Member J should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'J', + rank: 'field' + }, line: 13, column: 5 }, { - message: 'Member K should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'K', + rank: 'field' + }, line: 14, column: 5 }, { - message: 'Member L should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'L', + rank: 'field' + }, line: 15, column: 5 }, { - message: - 'Member new should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'new', + rank: 'field' + }, line: 16, column: 5 } @@ -1721,27 +1909,47 @@ type Foo = { ], errors: [ { - message: 'Member B should be declared before all method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'B', + rank: 'method' + }, line: 7, column: 5 }, { - message: 'Member C should be declared before all method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'C', + rank: 'method' + }, line: 9, column: 5 }, { - message: 'Member D should be declared before all method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'D', + rank: 'method' + }, line: 11, column: 5 }, { - message: 'Member E should be declared before all method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'E', + rank: 'method' + }, line: 13, column: 5 }, { - message: 'Member F should be declared before all method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'F', + rank: 'method' + }, line: 15, column: 5 } @@ -1767,20 +1975,29 @@ class Foo { `, errors: [ { - message: - 'Member G should be declared before all public instance method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'G', + rank: 'public instance method' + }, line: 13, column: 5 }, { - message: - 'Member H should be declared before all public instance method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'H', + rank: 'public instance method' + }, line: 14, column: 5 }, { - message: - 'Member I should be declared before all public instance method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'I', + rank: 'public instance method' + }, line: 15, column: 5 } @@ -1807,38 +2024,56 @@ class Foo { options: [{ default: ['field', 'constructor', 'method'] }], errors: [ { - message: - 'Member A should be declared before all constructor definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'A', + rank: 'constructor' + }, line: 4, column: 5 }, { - message: - 'Member B should be declared before all constructor definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'B', + rank: 'constructor' + }, line: 5, column: 5 }, { - message: - 'Member C should be declared before all constructor definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'C', + rank: 'constructor' + }, line: 6, column: 5 }, { - message: - 'Member D should be declared before all constructor definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'D', + rank: 'constructor' + }, line: 7, column: 5 }, { - message: - 'Member E should be declared before all constructor definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'E', + rank: 'constructor' + }, line: 8, column: 5 }, { - message: - 'Member F should be declared before all constructor definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'F', + rank: 'constructor' + }, line: 9, column: 5 } @@ -1865,7 +2100,11 @@ class Foo { options: [{ default: ['field', 'method'] }], errors: [ { - message: 'Member A should be declared before all method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'A', + rank: 'method' + }, line: 10, column: 5 } @@ -1892,7 +2131,11 @@ class Foo { options: [{ default: ['method', 'field'] }], errors: [ { - message: 'Member G should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'G', + rank: 'field' + }, line: 9, column: 5 } @@ -1919,28 +2162,47 @@ class Foo { options: [{ classes: ['method', 'constructor', 'field'] }], errors: [ { - message: 'Member I should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'I', + rank: 'field' + }, line: 6, column: 5 }, { - message: 'Member J should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'J', + rank: 'field' + }, line: 7, column: 5 }, { - message: 'Member K should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'K', + rank: 'field' + }, line: 8, column: 5 }, { - message: 'Member L should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'L', + rank: 'field' + }, line: 9, column: 5 }, { - message: - 'Member constructor should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'constructor', + rank: 'field' + }, line: 11, column: 5 } @@ -1972,38 +2234,65 @@ class Foo { ], errors: [ { - message: 'Member G should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'G', + rank: 'field' + }, line: 4, column: 5 }, { - message: 'Member H should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'H', + rank: 'field' + }, line: 5, column: 5 }, { - message: 'Member I should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'I', + rank: 'field' + }, line: 6, column: 5 }, { - message: 'Member J should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'J', + rank: 'field' + }, line: 7, column: 5 }, { - message: 'Member K should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'K', + rank: 'field' + }, line: 8, column: 5 }, { - message: 'Member L should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'L', + rank: 'field' + }, line: 9, column: 5 }, { - message: - 'Member constructor should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'constructor', + rank: 'field' + }, line: 10, column: 5 } @@ -2042,14 +2331,20 @@ class Foo { ], errors: [ { - message: - 'Member A should be declared before all private field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'A', + rank: 'private field' + }, line: 12, column: 5 }, { - message: - 'Member F should be declared before all protected field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'F', + rank: 'protected field' + }, line: 15, column: 5 } @@ -2089,14 +2384,20 @@ class Foo { ], errors: [ { - message: - 'Member H should be declared before all public instance method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'H', + rank: 'public instance method' + }, line: 6, column: 5 }, { - message: - 'Member constructor should be declared before all public field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'constructor', + rank: 'public field' + }, line: 10, column: 5 } @@ -2133,8 +2434,11 @@ class Foo { ], errors: [ { - message: - 'Member constructor should be declared before all method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'constructor', + rank: 'method' + }, line: 8, column: 5 } @@ -2173,14 +2477,20 @@ class Foo { ], errors: [ { - message: - 'Member G should be declared before all private static method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'G', + rank: 'private static method' + }, line: 5, column: 5 }, { - message: - 'Member H should be declared before all private static method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'H', + rank: 'private static method' + }, line: 6, column: 5 } @@ -2211,8 +2521,11 @@ class Foo { ], errors: [ { - message: - 'Member L should be declared before all protected static field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'L', + rank: 'protected static field' + }, line: 10, column: 5 } @@ -2244,8 +2557,11 @@ class Foo { ], errors: [ { - message: - 'Member J should be declared before all protected static field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'J', + rank: 'protected static field' + }, line: 8, column: 5 } @@ -2271,20 +2587,29 @@ const foo = class Foo { `, errors: [ { - message: - 'Member G should be declared before all public instance method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'G', + rank: 'public instance method' + }, line: 13, column: 5 }, { - message: - 'Member H should be declared before all public instance method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'H', + rank: 'public instance method' + }, line: 14, column: 5 }, { - message: - 'Member I should be declared before all public instance method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'I', + rank: 'public instance method' + }, line: 15, column: 5 } @@ -2311,38 +2636,56 @@ const foo = class { options: [{ default: ['field', 'constructor', 'method'] }], errors: [ { - message: - 'Member A should be declared before all constructor definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'A', + rank: 'constructor' + }, line: 4, column: 5 }, { - message: - 'Member B should be declared before all constructor definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'B', + rank: 'constructor' + }, line: 5, column: 5 }, { - message: - 'Member C should be declared before all constructor definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'C', + rank: 'constructor' + }, line: 6, column: 5 }, { - message: - 'Member D should be declared before all constructor definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'D', + rank: 'constructor' + }, line: 7, column: 5 }, { - message: - 'Member E should be declared before all constructor definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'E', + rank: 'constructor' + }, line: 8, column: 5 }, { - message: - 'Member F should be declared before all constructor definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'F', + rank: 'constructor' + }, line: 9, column: 5 } @@ -2369,7 +2712,11 @@ const foo = class { options: [{ default: ['field', 'method'] }], errors: [ { - message: 'Member A should be declared before all method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'A', + rank: 'method' + }, line: 10, column: 5 } @@ -2396,7 +2743,11 @@ const foo = class { options: [{ default: ['method', 'field'] }], errors: [ { - message: 'Member G should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'G', + rank: 'field' + }, line: 9, column: 5 } @@ -2423,28 +2774,47 @@ const foo = class { options: [{ classExpressions: ['method', 'constructor', 'field'] }], errors: [ { - message: 'Member I should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'I', + rank: 'field' + }, line: 6, column: 5 }, { - message: 'Member J should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'J', + rank: 'field' + }, line: 7, column: 5 }, { - message: 'Member K should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'K', + rank: 'field' + }, line: 8, column: 5 }, { - message: 'Member L should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'L', + rank: 'field' + }, line: 9, column: 5 }, { - message: - 'Member constructor should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'constructor', + rank: 'field' + }, line: 11, column: 5 } @@ -2476,38 +2846,65 @@ const foo = class { ], errors: [ { - message: 'Member G should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'G', + rank: 'field' + }, line: 4, column: 5 }, { - message: 'Member H should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'H', + rank: 'field' + }, line: 5, column: 5 }, { - message: 'Member I should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'I', + rank: 'field' + }, line: 6, column: 5 }, { - message: 'Member J should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'J', + rank: 'field' + }, line: 7, column: 5 }, { - message: 'Member K should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'K', + rank: 'field' + }, line: 8, column: 5 }, { - message: 'Member L should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'L', + rank: 'field' + }, line: 9, column: 5 }, { - message: - 'Member constructor should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'constructor', + rank: 'field' + }, line: 10, column: 5 } @@ -2546,14 +2943,20 @@ const foo = class { ], errors: [ { - message: - 'Member A should be declared before all private field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'A', + rank: 'private field' + }, line: 12, column: 5 }, { - message: - 'Member F should be declared before all protected field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'F', + rank: 'protected field' + }, line: 15, column: 5 } @@ -2593,14 +2996,20 @@ const foo = class { ], errors: [ { - message: - 'Member H should be declared before all public instance method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'H', + rank: 'public instance method' + }, line: 6, column: 5 }, { - message: - 'Member constructor should be declared before all public field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'constructor', + rank: 'public field' + }, line: 10, column: 5 } @@ -2637,8 +3046,11 @@ const foo = class { ], errors: [ { - message: - 'Member constructor should be declared before all method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'constructor', + rank: 'method' + }, line: 8, column: 5 } @@ -2677,14 +3089,20 @@ const foo = class { ], errors: [ { - message: - 'Member G should be declared before all private static method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'G', + rank: 'private static method' + }, line: 5, column: 5 }, { - message: - 'Member H should be declared before all private static method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'H', + rank: 'private static method' + }, line: 6, column: 5 } @@ -2719,8 +3137,11 @@ const foo = class { ], errors: [ { - message: - 'Member L should be declared before all protected static field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'L', + rank: 'protected static field' + }, line: 10, column: 5 } @@ -2752,8 +3173,11 @@ const foo = class { ], errors: [ { - message: - 'Member J should be declared before all protected static field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'J', + rank: 'protected static field' + }, line: 8, column: 5 } @@ -2771,14 +3195,20 @@ class Foo { `, errors: [ { - message: - 'Member A should be declared before all public instance method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'A', + rank: 'public instance method' + }, line: 4, column: 5 }, { - message: - 'Member constructor should be declared before all public instance method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'constructor', + rank: 'public instance method' + }, line: 5, column: 5 } @@ -2796,8 +3226,11 @@ class Foo { options: [{ default: ['method', 'constructor', 'field'] }], errors: [ { - message: - 'Member K should be declared before all constructor definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'K', + rank: 'constructor' + }, line: 5, column: 5 } @@ -2816,8 +3249,11 @@ class Foo { options: [{ default: ['method', 'constructor', 'field'] }], errors: [ { - message: - 'Member K should be declared before all constructor definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'K', + rank: 'constructor' + }, line: 5, column: 5 } @@ -2833,7 +3269,11 @@ interface Foo { `, errors: [ { - message: 'Member A should be declared before all method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'A', + rank: 'method' + }, line: 5, column: 5 } @@ -2849,7 +3289,11 @@ type Foo = { `, errors: [ { - message: 'Member A should be declared before all method definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'A', + rank: 'method' + }, line: 5, column: 5 } @@ -2866,7 +3310,11 @@ type Foo = { options: [{ default: ['method', 'constructor', 'field'] }], errors: [ { - message: 'Member J should be declared before all field definitions.', + messageId: 'incorrectOrder' as 'incorrectOrder', + data: { + name: 'J', + rank: 'field' + }, line: 5, column: 5 } From 5d1165e655703577c7a291a5adda4edf59249262 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Sun, 3 Feb 2019 19:15:35 -0800 Subject: [PATCH 46/92] review fixes --- .../src/rules/class-name-casing.ts | 23 ++++++++++--- .../typescript-estree/src/ast-node-types.ts | 17 ++++++++-- packages/typescript-estree/src/typedefs.ts | 33 +++---------------- 3 files changed, 38 insertions(+), 35 deletions(-) diff --git a/packages/eslint-plugin/src/rules/class-name-casing.ts b/packages/eslint-plugin/src/rules/class-name-casing.ts index bb3bdcda6cb3..d5efc76de26c 100644 --- a/packages/eslint-plugin/src/rules/class-name-casing.ts +++ b/packages/eslint-plugin/src/rules/class-name-casing.ts @@ -6,7 +6,7 @@ import RuleModule from 'ts-eslint'; import * as util from '../util'; -import { TSESTree } from '@typescript-eslint/typescript-estree'; +import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; //------------------------------------------------------------------------------ // Rule Definition @@ -95,11 +95,24 @@ const rule: RuleModule = { "VariableDeclarator[init.type='ClassExpression']"( node: TSESTree.VariableDeclarator ) { - const id = node.id as TSESTree.Identifier; - const nodeInit = node.init as TSESTree.ClassExpression; + if ( + node.id.type === AST_NODE_TYPES.ArrayPattern || + node.id.type === AST_NODE_TYPES.ObjectPattern + ) { + // TODO - handle the BindingPattern case maybe? + /* + // this example makes me barf, but it's valid code + var { bar } = class { + static bar() { return 2 } + } + */ + } else { + const id = node.id; + const nodeInit = node.init as TSESTree.ClassExpression; - if (id && !nodeInit.id && !isPascalCase(id.name)) { - report(nodeInit, id); + if (id && !nodeInit.id && !isPascalCase(id.name)) { + report(nodeInit, id); + } } } }; diff --git a/packages/typescript-estree/src/ast-node-types.ts b/packages/typescript-estree/src/ast-node-types.ts index aa370d2e97a1..4fd998652eec 100644 --- a/packages/typescript-estree/src/ast-node-types.ts +++ b/packages/typescript-estree/src/ast-node-types.ts @@ -104,14 +104,12 @@ export enum AST_NODE_TYPES { TSBooleanKeyword = 'TSBooleanKeyword', TSBigIntKeyword = 'TSBigIntKeyword', TSConditionalType = 'TSConditionalType', - TSConstKeyword = 'TSConstKeyword', TSConstructorType = 'TSConstructorType', TSCallSignatureDeclaration = 'TSCallSignatureDeclaration', TSClassImplements = 'TSClassImplements', TSConstructSignatureDeclaration = 'TSConstructSignatureDeclaration', TSDeclareKeyword = 'TSDeclareKeyword', TSDeclareFunction = 'TSDeclareFunction', - TSDefaultKeyword = 'TSDefaultKeyword', TSEnumDeclaration = 'TSEnumDeclaration', TSEnumMember = 'TSEnumMember', TSExportAssignment = 'TSExportAssignment', @@ -170,3 +168,18 @@ export enum AST_NODE_TYPES { TSUnknownKeyword = 'TSUnknownKeyword', TSVoidKeyword = 'TSVoidKeyword' } + +export enum AST_TOKEN_TYPES { + Boolean = 'Boolean', + Identifier = 'Identifier', + JSXIdentifier = 'JSXIdentifier', + JSXMemberExpression = 'JSXMemberExpression', + JSXText = 'JSXText', + Keyword = 'Keyword', + Null = 'Null', + Numeric = 'Numeric', + Punctuator = 'Punctuator', + RegularExpression = 'RegularExpression', + String = 'String', + Template = 'Template' +} diff --git a/packages/typescript-estree/src/typedefs.ts b/packages/typescript-estree/src/typedefs.ts index d41a9d431300..807fd13928c4 100644 --- a/packages/typescript-estree/src/typedefs.ts +++ b/packages/typescript-estree/src/typedefs.ts @@ -1,4 +1,4 @@ -import { AST_NODE_TYPES } from './ast-node-types'; +import { AST_NODE_TYPES, AST_TOKEN_TYPES } from './ast-node-types'; export interface LineAndColumnData { /** @@ -53,19 +53,7 @@ interface BaseNode { */ export interface Token extends BaseNode { - type: - | 'Boolean' - | 'Identifier' - | 'JSXIdentifier' - | 'JSXMemberExpression' - | 'JSXText' - | 'Keyword' - | 'Null' - | 'Numeric' - | 'Punctuator' - | 'RegularExpression' - | 'String' - | 'Template'; + type: AST_TOKEN_TYPES; value: string; regex?: { pattern: string; @@ -168,12 +156,10 @@ export type Node = | TSCallSignatureDeclaration | TSClassImplements | TSConditionalType - | TSConstKeyword | TSConstructorType | TSConstructSignatureDeclaration | TSDeclareFunction | TSDeclareKeyword - | TSDefaultKeyword | TSEnumDeclaration | TSEnumMember | TSExportAssignment @@ -330,9 +316,7 @@ export type LiteralExpression = BigIntLiteral | Literal | TemplateLiteral; export type Modifier = | TSAbstractKeyword | TSAsyncKeyword - | TSConstKeyword | TSDeclareKeyword - | TSDefaultKeyword | TSExportKeyword | TSPublicKeyword | TSPrivateKeyword @@ -789,7 +773,8 @@ export interface JSXIdentifier extends BaseNode { export interface JSXMemberExpression extends BaseNode { type: AST_NODE_TYPES.JSXMemberExpression; - name: string; + object: JSXTagNameExpression; + property: JSXIdentifier; } export interface JSXOpeningElement extends BaseNode { @@ -873,7 +858,7 @@ export interface ObjectPattern extends BaseNode { export interface Program extends BaseNode { type: AST_NODE_TYPES.Program; body: Statement[]; - sourcetype: 'module' | 'script'; + sourceType: 'module' | 'script'; comments?: Comment[]; tokens?: Token[]; } @@ -1021,10 +1006,6 @@ export interface TSConditionalType extends BaseNode { falseType: TypeNode; } -export interface TSConstKeyword extends BaseNode { - type: AST_NODE_TYPES.TSConstKeyword; -} - export interface TSConstructorType extends FunctionSignatureBase { type: AST_NODE_TYPES.TSConstructorType; } @@ -1041,10 +1022,6 @@ export interface TSDeclareKeyword extends BaseNode { type: AST_NODE_TYPES.TSDeclareKeyword; } -export interface TSDefaultKeyword extends BaseNode { - type: AST_NODE_TYPES.TSDefaultKeyword; -} - export interface TSEnumDeclaration extends BaseNode { type: AST_NODE_TYPES.TSEnumDeclaration; id: Identifier; From 6ef013a9c30b241964d6e36a40235190ab6d8e62 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Sun, 3 Feb 2019 19:24:07 -0800 Subject: [PATCH 47/92] no-angle-bracket-type-assertion --- .../src/rules/adjacent-overload-signatures.ts | 32 ++++----------- .../rules/no-angle-bracket-type-assertion.ts | 17 +++++--- .../no-angle-bracket-type-assertion.test.ts | 40 +++++++++++++------ 3 files changed, 48 insertions(+), 41 deletions(-) diff --git a/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts b/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts index 4adcf6edbf34..4d831266a586 100644 --- a/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts +++ b/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts @@ -6,6 +6,7 @@ import { TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; +import { getNameFromPropertyName } from '../tsestree-utils'; //------------------------------------------------------------------------------ // Rule Definition @@ -65,33 +66,16 @@ const rule: RuleModule = { return getMemberName(member.declaration); } case 'TSDeclareFunction': - case 'FunctionDeclaration': { + case 'FunctionDeclaration': return member.id && member.id.name; - } - case 'TSMethodSignature': { - if (member.key.type === 'Identifier') { - return member.key.name; - } else if (member.key.type === 'Literal') { - return member.key.value; - } - - return null; - } - case 'TSCallSignatureDeclaration': { + case 'TSMethodSignature': + return getNameFromPropertyName(member.key); + case 'TSCallSignatureDeclaration': return 'call'; - } - case 'TSConstructSignatureDeclaration': { + case 'TSConstructSignatureDeclaration': return 'new'; - } - case 'MethodDefinition': { - if (member.key.type === 'Identifier') { - return member.key.name; - } else if (member.key.type === 'Literal') { - return member.key.value; - } - - return null; - } + case 'MethodDefinition': + return getNameFromPropertyName(member.key); } return null; diff --git a/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts b/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts index a34af0e3cad1..e970467c2d66 100644 --- a/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts @@ -3,6 +3,7 @@ * @author Patricio Trevino */ +import { TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; @@ -10,17 +11,24 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -const rule: RuleModule = { +type Options = []; +type MessageIds = 'preferAs'; + +const rule: RuleModule = { meta: { type: 'problem', docs: { description: 'Enforces the use of `as Type` assertions instead of `` assertions', extraDescription: [util.tslintRule('no-angle-bracket-type-assertion')], - category: 'Style', + category: 'Stylistic Issues', url: util.metaDocsUrl('no-angle-bracket-type-assertion'), recommended: 'error' }, + messages: { + preferAs: + "Prefer 'as {{cast}}' instead of '<{{cast}}>' when doing type assertions." + }, schema: [] }, @@ -31,11 +39,10 @@ const rule: RuleModule = { // Public //---------------------------------------------------------------------- return { - TSTypeAssertion(node) { + TSTypeAssertion(node: TSESTree.TSTypeAssertion) { context.report({ node, - message: - "Prefer 'as {{cast}}' instead of '<{{cast}}>' when doing type assertions.", + messageId: 'preferAs', data: { cast: sourceCode.getText(node.typeAnnotation) } diff --git a/packages/eslint-plugin/tests/rules/no-angle-bracket-type-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-angle-bracket-type-assertion.test.ts index 3db2ad84958f..e44aa4a85c2b 100644 --- a/packages/eslint-plugin/tests/rules/no-angle-bracket-type-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-angle-bracket-type-assertion.test.ts @@ -72,14 +72,18 @@ const bar = new Generic(); `, errors: [ { - message: - "Prefer 'as Foo' instead of '' when doing type assertions.", + messageId: 'preferAs', + data: { + cast: 'Foo' + }, line: 9, column: 13 }, { - message: - "Prefer 'as Foo' instead of '' when doing type assertions.", + messageId: 'preferAs', + data: { + cast: 'Foo' + }, line: 10, column: 13 } @@ -89,8 +93,10 @@ const bar = new Generic(); code: 'const a : number = 5', errors: [ { - message: - "Prefer 'as number' instead of '' when doing type assertions.", + messageId: 'preferAs', + data: { + cast: 'number' + }, line: 1, column: 20 } @@ -103,8 +109,10 @@ const b : number = a; `, errors: [ { - message: - "Prefer 'as number' instead of '' when doing type assertions.", + messageId: 'preferAs', + data: { + cast: 'number' + }, line: 3, column: 20 } @@ -114,8 +122,10 @@ const b : number = a; code: 'const a : Array = >[1];', errors: [ { - message: - "Prefer 'as Array' instead of '>' when doing type assertions.", + messageId: 'preferAs', + data: { + cast: 'Array' + }, line: 1, column: 27 } @@ -131,7 +141,10 @@ const a : A = b; `, errors: [ { - message: "Prefer 'as A' instead of '' when doing type assertions.", + messageId: 'preferAs', + data: { + cast: 'A' + }, line: 6, column: 15 } @@ -151,7 +164,10 @@ const a: A = b; `, errors: [ { - message: "Prefer 'as A' instead of '' when doing type assertions.", + messageId: 'preferAs', + data: { + cast: 'A' + }, line: 10, column: 14 } From 8309b5da8302789607adcbae7d798f4263692449 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Sun, 3 Feb 2019 19:27:20 -0800 Subject: [PATCH 48/92] no-array-constructor --- .../src/rules/no-array-constructor.ts | 18 ++++++++++++------ .../tests/rules/no-array-constructor.test.ts | 18 +++++++++--------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-array-constructor.ts b/packages/eslint-plugin/src/rules/no-array-constructor.ts index 82715a6332f0..b0cb752b6f7d 100644 --- a/packages/eslint-plugin/src/rules/no-array-constructor.ts +++ b/packages/eslint-plugin/src/rules/no-array-constructor.ts @@ -6,12 +6,15 @@ import RuleModule from 'ts-eslint'; import * as util from '../util'; +import { TSESTree } from '@typescript-eslint/typescript-estree'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ +export type Options = []; +export type MessageIds = 'useLiteral'; -const rule: RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { @@ -21,17 +24,20 @@ const rule: RuleModule = { recommended: 'error' }, fixable: 'code', + messages: { + useLiteral: 'The array literal notation [] is preferrable.' + }, schema: [] }, create(context) { /** * Disallow construction of dense arrays using the Array constructor - * @param {ASTNode} node node to evaluate - * @returns {void} - * @private + * @param node node to evaluate */ - function check(node) { + function check( + node: TSESTree.CallExpression | TSESTree.NewExpression + ): void { if ( node.arguments.length !== 1 && node.callee.type === 'Identifier' && @@ -40,7 +46,7 @@ const rule: RuleModule = { ) { context.report({ node, - message: 'The array literal notation [] is preferrable.', + messageId: 'useLiteral', fix(fixer) { if (node.arguments.length === 0) { return fixer.replaceText(node, '[]'); diff --git a/packages/eslint-plugin/tests/rules/no-array-constructor.test.ts b/packages/eslint-plugin/tests/rules/no-array-constructor.test.ts index b87857703844..f0c0fda1639d 100644 --- a/packages/eslint-plugin/tests/rules/no-array-constructor.test.ts +++ b/packages/eslint-plugin/tests/rules/no-array-constructor.test.ts @@ -19,7 +19,7 @@ const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); -const message = 'The array literal notation [] is preferrable.'; +const messageId = 'useLiteral' as 'useLiteral'; ruleTester.run('no-array-constructor', rule, { valid: [ @@ -43,37 +43,37 @@ ruleTester.run('no-array-constructor', rule, { { code: 'new Array()', output: '[]', - errors: [{ message, type: 'NewExpression' }] + errors: [{ messageId }] }, { code: 'Array()', output: '[]', - errors: [{ message, type: 'CallExpression' }] + errors: [{ messageId }] }, { code: 'new Array', output: '[]', - errors: [{ message, type: 'NewExpression' }] + errors: [{ messageId }] }, { code: 'new Array(x, y)', output: '[x, y]', - errors: [{ message, type: 'NewExpression' }] + errors: [{ messageId }] }, { code: 'Array(x, y)', output: '[x, y]', - errors: [{ message, type: 'CallExpression' }] + errors: [{ messageId }] }, { code: 'new Array(0, 1, 2)', output: '[0, 1, 2]', - errors: [{ message, type: 'NewExpression' }] + errors: [{ messageId }] }, { code: 'Array(0, 1, 2)', output: '[0, 1, 2]', - errors: [{ message, type: 'CallExpression' }] + errors: [{ messageId }] }, { code: `new Array( @@ -86,7 +86,7 @@ ruleTester.run('no-array-constructor', rule, { 1, 2 ]`, - errors: [{ message, type: 'NewExpression' }] + errors: [{ messageId }] } ] }); From 4252c4ab7e2e840a656a8a5454ff26a0e1a0bdd1 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Sun, 3 Feb 2019 19:30:41 -0800 Subject: [PATCH 49/92] no-empty-interface --- .../src/rules/no-empty-interface.ts | 27 ++++++++++++------- .../tests/rules/no-empty-interface.test.ts | 7 +++-- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-empty-interface.ts b/packages/eslint-plugin/src/rules/no-empty-interface.ts index 5ca9a111da00..8213a5af91be 100644 --- a/packages/eslint-plugin/src/rules/no-empty-interface.ts +++ b/packages/eslint-plugin/src/rules/no-empty-interface.ts @@ -3,6 +3,7 @@ * @author Patricio Trevino */ +import { TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; @@ -10,16 +11,24 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -const rule: RuleModule = { +type Options = []; +type MessageIds = 'noEmpty' | 'noEmptyWithSuper'; + +const rule: RuleModule = { meta: { type: 'suggestion', docs: { description: 'Disallow the declaration of empty interfaces', extraDescription: [util.tslintRule('no-empty-interface')], - category: 'TypeScript', + category: 'Best Practices', url: util.metaDocsUrl('no-empty-interface'), recommended: 'error' }, + messages: { + noEmpty: 'An empty interface is equivalent to `{}`.', + noEmptyWithSuper: + 'An interface declaring no members is equivalent to its supertype.' + }, schema: [] }, @@ -29,23 +38,23 @@ const rule: RuleModule = { create(context) { return { - TSInterfaceDeclaration(node) { + TSInterfaceDeclaration(node: TSESTree.TSInterfaceDeclaration) { if (node.body.body.length !== 0) { return; } - let message; + let messageId: MessageIds | null = null; if (!node.extends || node.extends.length === 0) { - message = 'An empty interface is equivalent to `{}`.'; + messageId = 'noEmpty'; } else if (node.extends.length === 1) { - message = - 'An interface declaring no members is equivalent to its supertype.'; + messageId = 'noEmptyWithSuper'; } - if (!message) { + if (!messageId) { return; } + context.report({ node: node.id, - message + messageId }); } }; diff --git a/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts b/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts index 1af52a3299c9..4c02ca466520 100644 --- a/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts +++ b/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts @@ -43,7 +43,7 @@ interface Baz extends Foo, Bar {} code: 'interface Foo {}', errors: [ { - message: 'An empty interface is equivalent to `{}`.', + messageId: 'noEmpty', line: 1, column: 11 } @@ -53,7 +53,7 @@ interface Baz extends Foo, Bar {} code: 'interface Foo extends {}', errors: [ { - message: 'An empty interface is equivalent to `{}`.', + messageId: 'noEmpty', line: 1, column: 11 } @@ -69,8 +69,7 @@ interface Bar extends Foo {} `, errors: [ { - message: - 'An interface declaring no members is equivalent to its supertype.', + messageId: 'noEmptyWithSuper', line: 6, column: 11 } From efb0e9bd35743a679585fa92954327ffef0360f6 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Sun, 3 Feb 2019 19:32:18 -0800 Subject: [PATCH 50/92] no-explicit-any --- .../src/rules/no-explicit-any.ts | 12 ++- .../tests/rules/no-explicit-any.test.ts | 94 +++++++++---------- 2 files changed, 56 insertions(+), 50 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-explicit-any.ts b/packages/eslint-plugin/src/rules/no-explicit-any.ts index 97a7198a1d7e..94635af73990 100644 --- a/packages/eslint-plugin/src/rules/no-explicit-any.ts +++ b/packages/eslint-plugin/src/rules/no-explicit-any.ts @@ -11,16 +11,22 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -const rule: RuleModule = { +type Options = []; +type MessageIds = 'unexpectedAny'; + +const rule: RuleModule = { meta: { type: 'suggestion', docs: { description: 'Disallow usage of the `any` type', extraDescription: [util.tslintRule('no-any')], - category: 'TypeScript', + category: 'Best Practices', url: util.metaDocsUrl('no-explicit-any'), recommended: 'warn' }, + messages: { + unexpectedAny: 'Unexpected any. Specify a different type.' + }, schema: [] }, @@ -29,7 +35,7 @@ const rule: RuleModule = { TSAnyKeyword(node) { context.report({ node, - message: 'Unexpected any. Specify a different type.' + messageId: 'unexpectedAny' }); } }; diff --git a/packages/eslint-plugin/tests/rules/no-explicit-any.test.ts b/packages/eslint-plugin/tests/rules/no-explicit-any.test.ts index c1f7f4aa56ff..a4e9db77fc66 100644 --- a/packages/eslint-plugin/tests/rules/no-explicit-any.test.ts +++ b/packages/eslint-plugin/tests/rules/no-explicit-any.test.ts @@ -148,7 +148,7 @@ type obj = { code: 'const number: any = 1', errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 1, column: 15 } @@ -158,7 +158,7 @@ type obj = { code: 'function generic(): any {}', errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 1, column: 21 } @@ -168,7 +168,7 @@ type obj = { code: 'function generic(): Array {}', errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 1, column: 27 } @@ -178,7 +178,7 @@ type obj = { code: 'function generic(): any[] {}', errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 1, column: 21 } @@ -188,7 +188,7 @@ type obj = { code: 'function generic(param: Array): number {}', errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 1, column: 31 } @@ -198,7 +198,7 @@ type obj = { code: 'function generic(param: any[]): number {}', errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 1, column: 25 } @@ -208,12 +208,12 @@ type obj = { code: 'function generic(param: Array): Array {}', errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 1, column: 31 }, { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 1, column: 44 } @@ -223,7 +223,7 @@ type obj = { code: 'function generic(): Array> {}', errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 1, column: 33 } @@ -233,7 +233,7 @@ type obj = { code: 'function generic(): Array {}', errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 1, column: 27 } @@ -247,7 +247,7 @@ class Greeter { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 30 } @@ -261,7 +261,7 @@ class Greeter { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 14 } @@ -275,7 +275,7 @@ class Greeter { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 20 } @@ -289,7 +289,7 @@ class Greeter { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 14 } @@ -303,7 +303,7 @@ class Greeter { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 26 } @@ -317,7 +317,7 @@ class Greeter { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 20 } @@ -331,7 +331,7 @@ interface Greeter { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 14 } @@ -345,7 +345,7 @@ interface Greeter { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 20 } @@ -359,7 +359,7 @@ interface Greeter { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 14 } @@ -373,7 +373,7 @@ interface Greeter { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 26 } @@ -387,7 +387,7 @@ interface Greeter { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 20 } @@ -401,7 +401,7 @@ type obj = { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 14 } @@ -415,7 +415,7 @@ type obj = { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 20 } @@ -429,7 +429,7 @@ type obj = { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 14 } @@ -443,7 +443,7 @@ type obj = { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 26 } @@ -457,7 +457,7 @@ type obj = { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 20 } @@ -471,7 +471,7 @@ type obj = { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 23 } @@ -485,7 +485,7 @@ type obj = { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 29 } @@ -499,7 +499,7 @@ type obj = { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 23 } @@ -513,7 +513,7 @@ type obj = { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 35 } @@ -527,7 +527,7 @@ type obj = { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 29 } @@ -541,7 +541,7 @@ type obj = { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 23 } @@ -555,7 +555,7 @@ type obj = { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 29 } @@ -569,7 +569,7 @@ type obj = { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 23 } @@ -583,7 +583,7 @@ type obj = { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 35 } @@ -597,7 +597,7 @@ type obj = { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 29 } @@ -607,12 +607,12 @@ type obj = { code: `class Foo extends Bar {}`, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 1, column: 15 }, { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 1, column: 32 } @@ -622,12 +622,12 @@ type obj = { code: `abstract class Foo extends Bar {}`, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 1, column: 24 }, { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 1, column: 41 } @@ -637,17 +637,17 @@ type obj = { code: `abstract class Foo implements Bar, Baz {}`, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 1, column: 24 }, { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 1, column: 44 }, { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 1, column: 54 } @@ -657,7 +657,7 @@ type obj = { code: `new Foo()`, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 1, column: 9 } @@ -667,7 +667,7 @@ type obj = { code: `Foo()`, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 1, column: 5 } @@ -681,12 +681,12 @@ type obj = { `, errors: [ { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 2, column: 41 }, { - message: 'Unexpected any. Specify a different type.', + messageId: 'unexpectedAny', line: 3, column: 41 } From 22ab757088c9519004e23e67e00482d4d039cc6d Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Sun, 3 Feb 2019 19:41:58 -0800 Subject: [PATCH 51/92] no-extraneous-class --- .../src/rules/no-extraneous-class.ts | 48 ++++++++++++++----- .../tests/rules/no-extraneous-class.test.ts | 12 +++-- 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-extraneous-class.ts b/packages/eslint-plugin/src/rules/no-extraneous-class.ts index e1243623fa1c..2cfe77be8a7c 100644 --- a/packages/eslint-plugin/src/rules/no-extraneous-class.ts +++ b/packages/eslint-plugin/src/rules/no-extraneous-class.ts @@ -3,6 +3,7 @@ * @author Jed Fox */ +import { TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; @@ -10,7 +11,16 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -const defaultOptions = [ +type Options = [ + { + allowConstructorOnly?: boolean; + allowEmpty?: boolean; + allowStaticOnly?: boolean; + } +]; +type MessageIds = 'empty' | 'onlyStatic' | 'onlyConstructor'; + +const defaultOptions: Options = [ { allowConstructorOnly: false, allowEmpty: false, @@ -18,7 +28,7 @@ const defaultOptions = [ } ]; -const rule: RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { @@ -28,7 +38,6 @@ const rule: RuleModule = { url: util.metaDocsUrl('no-extraneous-class'), recommended: false }, - fixable: null, schema: [ { type: 'object', @@ -61,14 +70,26 @@ const rule: RuleModule = { } = util.applyDefault(defaultOptions, context.options)[0]; return { - ClassBody(node) { - const { id, superClass } = node.parent; + ClassBody(node: TSESTree.ClassBody) { + const parent = node.parent as + | TSESTree.ClassDeclaration + | TSESTree.ClassExpression + | undefined; - if (superClass) return; + if (!parent || parent.superClass) { + return; + } if (node.body.length === 0) { - if (allowEmpty) return; - context.report({ node: id, messageId: 'empty' }); + if (allowEmpty) { + return; + } + + context.report({ + node, + messageId: 'empty' + }); + return; } @@ -76,7 +97,7 @@ const rule: RuleModule = { let onlyConstructor = true; for (const prop of node.body) { - if (prop.kind === 'constructor') { + if ('kind' in prop && prop.kind === 'constructor') { if ( prop.value.params.some( param => param.type === 'TSParameterProperty' @@ -87,7 +108,7 @@ const rule: RuleModule = { } } else { onlyConstructor = false; - if (!prop.static) { + if ('static' in prop && !prop.static) { onlyStatic = false; } } @@ -97,14 +118,17 @@ const rule: RuleModule = { if (onlyConstructor) { if (!allowConstructorOnly) { context.report({ - node: id, + node, messageId: 'onlyConstructor' }); } return; } if (onlyStatic && !allowStaticOnly) { - context.report({ node: id, messageId: 'onlyStatic' }); + context.report({ + node, + messageId: 'onlyStatic' + }); } } }; diff --git a/packages/eslint-plugin/tests/rules/no-extraneous-class.test.ts b/packages/eslint-plugin/tests/rules/no-extraneous-class.test.ts index 6a895e66f272..36831eb87459 100644 --- a/packages/eslint-plugin/tests/rules/no-extraneous-class.test.ts +++ b/packages/eslint-plugin/tests/rules/no-extraneous-class.test.ts @@ -11,9 +11,15 @@ import rule from '../../src/rules/no-extraneous-class'; import RuleTester from '../RuleTester'; -const empty = { messageId: 'empty', type: 'Identifier' }; -const onlyStatic = { messageId: 'onlyStatic', type: 'Identifier' }; -const onlyConstructor = { messageId: 'onlyConstructor', type: 'Identifier' }; +const empty = { + messageId: 'empty' as 'empty' +}; +const onlyStatic = { + messageId: 'onlyStatic' as 'onlyStatic' +}; +const onlyConstructor = { + messageId: 'onlyConstructor' as 'onlyConstructor' +}; //------------------------------------------------------------------------------ // Tests From 5ef1e40c49955763f3be2923e53c3fcf388c2bb8 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Sun, 3 Feb 2019 19:57:12 -0800 Subject: [PATCH 52/92] no-inferrable-types --- .../src/rules/no-inferrable-types.ts | 141 +++++++++++------- .../tests/rules/no-inferrable-types.test.ts | 60 +++++--- 2 files changed, 125 insertions(+), 76 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-inferrable-types.ts b/packages/eslint-plugin/src/rules/no-inferrable-types.ts index 9f004488c3fa..c87707546a90 100644 --- a/packages/eslint-plugin/src/rules/no-inferrable-types.ts +++ b/packages/eslint-plugin/src/rules/no-inferrable-types.ts @@ -5,30 +5,43 @@ import RuleModule from 'ts-eslint'; import * as util from '../util'; +import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -const defaultOptions = [ +type Options = [ + { + ignoreParameters?: boolean; + ignoreProperties?: boolean; + } +]; +type MessageIds = 'noInferrableType'; + +const defaultOptions: Options = [ { ignoreParameters: true, ignoreProperties: true } ]; -const rule: RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { description: 'Disallows explicit type declarations for variables or parameters initialized to a number, string, or boolean.', extraDescription: [util.tslintRule('no-inferrable-types')], - category: 'TypeScript', + category: 'Best Practices', url: util.metaDocsUrl('no-inferrable-types'), recommended: 'error' }, fixable: 'code', + messages: { + noInferrableType: + 'Type {{type}} trivially inferred from a {{type}} literal, remove type annotation.' + }, schema: [ { type: 'object', @@ -53,11 +66,17 @@ const rule: RuleModule = { /** * Returns whether a node has an inferrable value or not - * @param {ASTNode} node the node to check - * @param {ASTNode} init the initializer + * @param node the node to check + * @param init the initializer */ - function isInferrable(node, init): boolean { - if (node.type !== 'TSTypeAnnotation' || !node.typeAnnotation) { + function isInferrable( + node: TSESTree.TSTypeAnnotation, + init: TSESTree.Expression + ): boolean { + if ( + node.type !== AST_NODE_TYPES.TSTypeAnnotation || + !node.typeAnnotation + ) { return false; } @@ -67,31 +86,32 @@ const rule: RuleModule = { const annotation = node.typeAnnotation; - if (annotation.type === 'TSStringKeyword') { - return ( - (init.type === 'Literal' && typeof init.value === 'string') || - (init.type === 'TemplateElement' && - (!init.expressions || init.expressions.length === 0)) - ); + if (annotation.type === AST_NODE_TYPES.TSStringKeyword) { + if (init.type === AST_NODE_TYPES.Literal) { + return typeof init.value === 'string'; + } + return false; } - if (annotation.type === 'TSBooleanKeyword') { - return init.type === 'Literal'; + if (annotation.type === AST_NODE_TYPES.TSBooleanKeyword) { + return init.type === AST_NODE_TYPES.Literal; } - if (annotation.type === 'TSNumberKeyword') { + if (annotation.type === AST_NODE_TYPES.TSNumberKeyword) { // Infinity is special if ( - (init.type === 'UnaryExpression' && + (init.type === AST_NODE_TYPES.UnaryExpression && init.operator === '-' && - init.argument.type === 'Identifier' && + init.argument.type === AST_NODE_TYPES.Identifier && init.argument.name === 'Infinity') || - (init.type === 'Identifier' && init.name === 'Infinity') + (init.type === AST_NODE_TYPES.Identifier && init.name === 'Infinity') ) { return true; } - return init.type === 'Literal' && typeof init.value === 'number'; + return ( + init.type === AST_NODE_TYPES.Literal && typeof init.value === 'number' + ); } return false; @@ -99,11 +119,18 @@ const rule: RuleModule = { /** * Reports an inferrable type declaration, if any - * @param {ASTNode} node the node being visited - * @param {ASTNode} typeNode the type annotation node - * @param {ASTNode} initNode the initializer node + * @param node the node being visited + * @param typeNode the type annotation node + * @param initNode the initializer node */ - function reportInferrableType(node, typeNode, initNode): void { + function reportInferrableType( + node: + | TSESTree.VariableDeclarator + | TSESTree.Parameter + | TSESTree.ClassProperty, + typeNode: TSESTree.TSTypeAnnotation | undefined, + initNode: TSESTree.Expression | null | undefined + ): void { if (!typeNode || !initNode || !typeNode.typeAnnotation) { return; } @@ -112,18 +139,25 @@ const rule: RuleModule = { return; } - const typeMap = { - TSBooleanKeyword: 'boolean', - TSNumberKeyword: 'number', - TSStringKeyword: 'string' - }; - - const type = typeMap[typeNode.typeAnnotation.type]; + let type = null; + if (typeNode.typeAnnotation.type === AST_NODE_TYPES.TSBooleanKeyword) { + type = 'boolean'; + } else if ( + typeNode.typeAnnotation.type === AST_NODE_TYPES.TSNumberKeyword + ) { + type = 'number'; + } else if ( + typeNode.typeAnnotation.type === AST_NODE_TYPES.TSStringKeyword + ) { + type = 'string'; + } else { + // shouldn't happen... + return; + } context.report({ node, - message: - 'Type {{type}} trivially inferred from a {{type}} literal, remove type annotation.', + messageId: 'noInferrableType', data: { type }, @@ -131,40 +165,35 @@ const rule: RuleModule = { }); } - /** - * Visits variables - * @param {ASTNode} node the node to be visited - */ - function inferrableVariableVisitor(node): void { + function inferrableVariableVisitor( + node: TSESTree.VariableDeclarator + ): void { if (!node.id) { return; } reportInferrableType(node, node.id.typeAnnotation, node.init); } - /** - * Visits parameters - * @param {ASTNode} node the node to be visited - */ - function inferrableParameterVisitor(node): void { + function inferrableParameterVisitor( + node: + | TSESTree.FunctionExpression + | TSESTree.FunctionDeclaration + | TSESTree.ArrowFunctionExpression + ): void { if (ignoreParameters || !node.params) { return; } - node.params - .filter( - param => - param.type === 'AssignmentPattern' && param.left && param.right - ) - .forEach(param => { - reportInferrableType(param, param.left.typeAnnotation, param.right); - }); + (node.params.filter( + param => + param.type === AST_NODE_TYPES.AssignmentPattern && + param.left && + param.right + ) as TSESTree.AssignmentPattern[]).forEach(param => { + reportInferrableType(param, param.left.typeAnnotation, param.right); + }); } - /** - * Visits properties - * @param {ASTNode} node the node to be visited - */ - function inferrablePropertyVisitor(node): void { + function inferrablePropertyVisitor(node: TSESTree.ClassProperty): void { // We ignore `readonly` because of Microsoft/TypeScript#14416 // Essentially a readonly property without a type // will result in its value being the type, leading to diff --git a/packages/eslint-plugin/tests/rules/no-inferrable-types.test.ts b/packages/eslint-plugin/tests/rules/no-inferrable-types.test.ts index 27bacd0c05a8..152ed4393bbf 100644 --- a/packages/eslint-plugin/tests/rules/no-inferrable-types.test.ts +++ b/packages/eslint-plugin/tests/rules/no-inferrable-types.test.ts @@ -63,8 +63,10 @@ ruleTester.run('no-inferrable-types', rule, { output: 'const a = 5', errors: [ { - message: - 'Type number trivially inferred from a number literal, remove type annotation.', + messageId: 'noInferrableType', + data: { + type: 'number' + }, line: 1, column: 7 } @@ -75,8 +77,10 @@ ruleTester.run('no-inferrable-types', rule, { output: 'const a = Infinity', errors: [ { - message: - 'Type number trivially inferred from a number literal, remove type annotation.', + messageId: 'noInferrableType', + data: { + type: 'number' + }, line: 1, column: 7 } @@ -87,8 +91,10 @@ ruleTester.run('no-inferrable-types', rule, { output: 'const a = true', errors: [ { - message: - 'Type boolean trivially inferred from a boolean literal, remove type annotation.', + messageId: 'noInferrableType', + data: { + type: 'boolean' + }, line: 1, column: 7 } @@ -99,8 +105,10 @@ ruleTester.run('no-inferrable-types', rule, { output: "const a = 'foo'", errors: [ { - message: - 'Type string trivially inferred from a string literal, remove type annotation.', + messageId: 'noInferrableType', + data: { + type: 'string' + }, line: 1, column: 7 } @@ -118,20 +126,26 @@ ruleTester.run('no-inferrable-types', rule, { ], errors: [ { - message: - 'Type number trivially inferred from a number literal, remove type annotation.', + messageId: 'noInferrableType', + data: { + type: 'number' + }, line: 1, column: 13 }, { - message: - 'Type boolean trivially inferred from a boolean literal, remove type annotation.', + messageId: 'noInferrableType', + data: { + type: 'boolean' + }, line: 1, column: 28 }, { - message: - 'Type string trivially inferred from a string literal, remove type annotation.', + messageId: 'noInferrableType', + data: { + type: 'string' + }, line: 1, column: 47 } @@ -149,20 +163,26 @@ ruleTester.run('no-inferrable-types', rule, { ], errors: [ { - message: - 'Type number trivially inferred from a number literal, remove type annotation.', + messageId: 'noInferrableType', + data: { + type: 'number' + }, line: 1, column: 13 }, { - message: - 'Type boolean trivially inferred from a boolean literal, remove type annotation.', + messageId: 'noInferrableType', + data: { + type: 'boolean' + }, line: 1, column: 28 }, { - message: - 'Type string trivially inferred from a string literal, remove type annotation.', + messageId: 'noInferrableType', + data: { + type: 'string' + }, line: 1, column: 47 } From 616e3a5c6eb0ea98c22d2f8252fde90091ea91b5 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Sun, 3 Feb 2019 20:56:46 -0800 Subject: [PATCH 53/92] no-misused-new --- .../src/rules/no-inferrable-types.ts | 2 +- .../eslint-plugin/src/rules/no-misused-new.ts | 58 ++++++++++++++----- .../typescript-estree/src/ast-node-types.ts | 1 + packages/typescript-estree/src/typedefs.ts | 9 ++- 4 files changed, 53 insertions(+), 17 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-inferrable-types.ts b/packages/eslint-plugin/src/rules/no-inferrable-types.ts index c87707546a90..17affc4ada7e 100644 --- a/packages/eslint-plugin/src/rules/no-inferrable-types.ts +++ b/packages/eslint-plugin/src/rules/no-inferrable-types.ts @@ -3,9 +3,9 @@ * @author James Garbutt */ +import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; -import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; //------------------------------------------------------------------------------ // Rule Definition diff --git a/packages/eslint-plugin/src/rules/no-misused-new.ts b/packages/eslint-plugin/src/rules/no-misused-new.ts index f51b3c916611..51e95881d301 100644 --- a/packages/eslint-plugin/src/rules/no-misused-new.ts +++ b/packages/eslint-plugin/src/rules/no-misused-new.ts @@ -3,6 +3,7 @@ * @author Armano */ +import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; @@ -10,13 +11,16 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -const rule: RuleModule = { +type Options = []; +type MessageIds = 'errorMessageInterface' | 'errorMessageClass'; + +const rule: RuleModule = { meta: { type: 'problem', docs: { description: 'Enforce valid definition of `new` and `constructor`.', extraDescription: [util.tslintRule('no-misused-new')], - category: 'TypeScript', + category: 'Best Practices', url: util.metaDocsUrl('no-misused-new'), recommended: 'error' }, @@ -36,7 +40,13 @@ const rule: RuleModule = { * @param {ASTNode} node type to be inspected. * @returns name of simple type or null */ - function getTypeReferenceName(node): string | null { + function getTypeReferenceName( + node: + | TSESTree.TSTypeAnnotation + | TSESTree.TypeNode + | TSESTree.EntityName + | undefined + ): string | null { if (node) { switch (node.type) { case 'TSTypeAnnotation': @@ -56,16 +66,31 @@ const rule: RuleModule = { * @param {ASTNode} parent parent node. * @param {ASTNode} returnType type to be compared */ - function isMatchingParentType(parent, returnType): boolean { - if (parent && parent.id && parent.id.type === 'Identifier') { + function isMatchingParentType( + parent: undefined | TSESTree.Node, + returnType: TSESTree.TSTypeAnnotation | undefined + ): boolean { + if ( + parent && + 'id' in parent && + parent.id && + parent.id.type === 'Identifier' + ) { return getTypeReferenceName(returnType) === parent.id.name; } return false; } return { - 'TSInterfaceBody > TSConstructSignatureDeclaration'(node) { - if (isMatchingParentType(node.parent.parent, node.returnType)) { + 'TSInterfaceBody > TSConstructSignatureDeclaration'( + node: TSESTree.TSConstructSignatureDeclaration + ) { + if ( + isMatchingParentType( + node.parent!.parent as TSESTree.TSInterfaceDeclaration, + node.returnType + ) + ) { // constructor context.report({ node, @@ -73,19 +98,22 @@ const rule: RuleModule = { }); } }, - "TSMethodSignature[key.name='constructor']"(node) { + "TSMethodSignature[key.name='constructor']"( + node: TSESTree.TSMethodSignature + ) { context.report({ node, messageId: 'errorMessageInterface' }); }, - "ClassBody > MethodDefinition[key.name='new']"(node) { - if ( - node.value && - (node.value.type === 'TSEmptyBodyFunctionExpression' || - (node.value.type === 'TSDeclareFunction' && !node.value.body)) - ) { - if (isMatchingParentType(node.parent.parent, node.value.returnType)) { + "ClassBody > MethodDefinition[key.name='new']"( + node: TSESTree.MethodDefinition + ) { + if (node.value.type === AST_NODE_TYPES.TSEmptyBodyFunctionExpression) { + if ( + node.parent && + isMatchingParentType(node.parent.parent, node.value.returnType) + ) { context.report({ node, messageId: 'errorMessageClass' diff --git a/packages/typescript-estree/src/ast-node-types.ts b/packages/typescript-estree/src/ast-node-types.ts index 4fd998652eec..2bb831920352 100644 --- a/packages/typescript-estree/src/ast-node-types.ts +++ b/packages/typescript-estree/src/ast-node-types.ts @@ -110,6 +110,7 @@ export enum AST_NODE_TYPES { TSConstructSignatureDeclaration = 'TSConstructSignatureDeclaration', TSDeclareKeyword = 'TSDeclareKeyword', TSDeclareFunction = 'TSDeclareFunction', + TSEmptyBodyFunctionExpression = 'TSEmptyBodyFunctionExpression', TSEnumDeclaration = 'TSEnumDeclaration', TSEnumMember = 'TSEnumMember', TSExportAssignment = 'TSExportAssignment', diff --git a/packages/typescript-estree/src/typedefs.ts b/packages/typescript-estree/src/typedefs.ts index 807fd13928c4..4c6b33e051eb 100644 --- a/packages/typescript-estree/src/typedefs.ts +++ b/packages/typescript-estree/src/typedefs.ts @@ -160,6 +160,7 @@ export type Node = | TSConstructSignatureDeclaration | TSDeclareFunction | TSDeclareKeyword + | TSEmptyBodyFunctionExpression | TSEnumDeclaration | TSEnumMember | TSExportAssignment @@ -239,6 +240,7 @@ export type ClassElement = | MethodDefinition | TSAbstractClassProperty | TSAbstractMethodDefinition + | TSEmptyBodyFunctionExpression | TSIndexSignature; export type DeclarationStatement = | ClassDeclaration @@ -484,7 +486,7 @@ interface LiteralBase extends BaseNode { interface MethodDefinitionBase extends BaseNode { key: PropertyName; - value: FunctionExpression; + value: FunctionExpression | TSEmptyBodyFunctionExpression; computed: boolean; static: boolean; kind: 'method' | 'get' | 'set' | 'constructor'; @@ -1022,6 +1024,11 @@ export interface TSDeclareKeyword extends BaseNode { type: AST_NODE_TYPES.TSDeclareKeyword; } +export interface TSEmptyBodyFunctionExpression extends FunctionDeclarationBase { + type: AST_NODE_TYPES.TSEmptyBodyFunctionExpression; + body: null; +} + export interface TSEnumDeclaration extends BaseNode { type: AST_NODE_TYPES.TSEnumDeclaration; id: Identifier; From 7f36b4b2dd41d531e82db288a69fdbe5da1ebb4f Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 4 Feb 2019 19:54:52 -0800 Subject: [PATCH 54/92] fix new tests + debug config --- .vscode/launch.json | 2 +- .../src/rules/no-unnecessary-type-assertion.ts | 2 +- .../arrow-parens.test.ts} | 4 ++-- .../no-unnecessary-type-assertion.test.ts} | 6 +++--- .../no-useless-constructor.ts} | 10 +++++++--- 5 files changed, 14 insertions(+), 10 deletions(-) rename packages/eslint-plugin/tests/{lib/eslint-rules/arrow-parens.js => eslint-rules/arrow-parens.test.ts} (91%) rename packages/eslint-plugin/tests/{lib/rules/no-unnecessary-type-assertion.js => rules/no-unnecessary-type-assertion.test.ts} (94%) rename packages/eslint-plugin/tests/{lib/rules/no-useless-constructor.js => rules/no-useless-constructor.ts} (93%) diff --git a/.vscode/launch.json b/.vscode/launch.json index 406829abcf05..15c6b1bbb3d7 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,10 +11,10 @@ "cwd": "${workspaceFolder}/packages/eslint-plugin/", "program": "${workspaceFolder}/node_modules/jest/bin/jest.js", "args": [ - "--colors", "--runInBand", "tests/rules/${fileBasenameNoExtension}" ], + "sourceMaps": true, "console": "integratedTerminal", "internalConsoleOptions": "neverOpen" } diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts b/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts index cc1d5705d46e..e218831c888c 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts @@ -5,7 +5,7 @@ import { TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; -import tsutils from 'tsutils'; +import * as tsutils from 'tsutils'; import ts from 'typescript'; import * as util from '../util'; diff --git a/packages/eslint-plugin/tests/lib/eslint-rules/arrow-parens.js b/packages/eslint-plugin/tests/eslint-rules/arrow-parens.test.ts similarity index 91% rename from packages/eslint-plugin/tests/lib/eslint-rules/arrow-parens.js rename to packages/eslint-plugin/tests/eslint-rules/arrow-parens.test.ts index e8a77ca2013d..373d4f0afc68 100644 --- a/packages/eslint-plugin/tests/lib/eslint-rules/arrow-parens.js +++ b/packages/eslint-plugin/tests/eslint-rules/arrow-parens.test.ts @@ -4,8 +4,8 @@ // Requirements //------------------------------------------------------------------------------ -const rule = require('eslint/lib/rules/arrow-parens'), - RuleTester = require('eslint').RuleTester; +import rule from 'eslint/lib/rules/arrow-parens'; +import RuleTester from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/lib/rules/no-unnecessary-type-assertion.js b/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts similarity index 94% rename from packages/eslint-plugin/tests/lib/rules/no-unnecessary-type-assertion.js rename to packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts index 633f1a334330..2f826bd21838 100644 --- a/packages/eslint-plugin/tests/lib/rules/no-unnecessary-type-assertion.js +++ b/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts @@ -8,9 +8,9 @@ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/no-unnecessary-type-assertion'), - RuleTester = require('eslint').RuleTester, - path = require('path'); +import path from 'path'; +import rule from '../../src/rules/no-unnecessary-type-assertion'; +import RuleTester from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/lib/rules/no-useless-constructor.js b/packages/eslint-plugin/tests/rules/no-useless-constructor.ts similarity index 93% rename from packages/eslint-plugin/tests/lib/rules/no-useless-constructor.js rename to packages/eslint-plugin/tests/rules/no-useless-constructor.ts index c73c5034f121..fb82cd639dce 100644 --- a/packages/eslint-plugin/tests/lib/rules/no-useless-constructor.js +++ b/packages/eslint-plugin/tests/rules/no-useless-constructor.ts @@ -4,8 +4,8 @@ // Requirements //------------------------------------------------------------------------------ -const rule = require('../../../lib/rules/no-useless-constructor'), - RuleTester = require('eslint').RuleTester; +import rule from '../../src/rules/no-type-alias'; +import RuleTester from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { @@ -15,7 +15,11 @@ const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); -const error = { message: 'Useless constructor.', type: 'MethodDefinition' }; +// the base rule doesn't use a message id... +const error: any = { + message: 'Useless constructor.', + type: 'MethodDefinition' +}; ruleTester.run('no-useless-constructor', rule, { valid: [ From 2a7fc49b330c1c87c38ea6761b50d20596ac4a6e Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 4 Feb 2019 19:55:15 -0800 Subject: [PATCH 55/92] no-namespace --- .../eslint-plugin/src/rules/no-namespace.ts | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-namespace.ts b/packages/eslint-plugin/src/rules/no-namespace.ts index 6fc44d7288fa..36d3751af4ac 100644 --- a/packages/eslint-plugin/src/rules/no-namespace.ts +++ b/packages/eslint-plugin/src/rules/no-namespace.ts @@ -3,7 +3,7 @@ * @author Patricio Trevino */ -import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; +import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; @@ -11,21 +11,29 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -const defaultOptions = [ +type Options = [ + { + allowDeclarations?: boolean; + allowDefinitionFiles?: boolean; + } +]; +type MessageIds = 'moduleSyntaxIsPreferred'; + +const defaultOptions: Options = [ { allowDeclarations: false, allowDefinitionFiles: true } ]; -const rule: RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { description: 'Disallow the use of custom TypeScript modules and namespaces', extraDescription: [util.tslintRule('no-namespace')], - category: 'TypeScript', + category: 'Best Practices', url: util.metaDocsUrl('no-namespace'), recommended: 'error' }, @@ -60,7 +68,9 @@ const rule: RuleModule = { // Public //---------------------------------------------------------------------- return { - "TSModuleDeclaration[global!=true][id.type='Identifier']"(node) { + "TSModuleDeclaration[global!=true][id.type='Identifier']"( + node: TSESTree.TSModuleDeclaration + ) { if ( (node.parent && node.parent.type === AST_NODE_TYPES.TSModuleDeclaration) || From 3ae13c69146319b093bc7e9023c6d2ccc8ee4e0f Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 4 Feb 2019 20:16:48 -0800 Subject: [PATCH 56/92] add types for the eslint modules used in eslint-rules tests --- .../tests/eslint-rules/strict.test.ts | 2 +- .../eslint-plugin/typings/eslint-rules.d.ts | 194 ++++++++++++++++++ 2 files changed, 195 insertions(+), 1 deletion(-) diff --git a/packages/eslint-plugin/tests/eslint-rules/strict.test.ts b/packages/eslint-plugin/tests/eslint-rules/strict.test.ts index d886a5bdb3a5..83edab4f2145 100644 --- a/packages/eslint-plugin/tests/eslint-rules/strict.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/strict.test.ts @@ -44,7 +44,7 @@ window.whatevs = { message: "Use the function form of 'use strict'.", line: 3, column: 9 - } + } as any // the base rule doesn't use messageId ] } ] diff --git a/packages/eslint-plugin/typings/eslint-rules.d.ts b/packages/eslint-plugin/typings/eslint-rules.d.ts index 84e38c1de0a6..c619f319e711 100644 --- a/packages/eslint-plugin/typings/eslint-rules.d.ts +++ b/packages/eslint-plugin/typings/eslint-rules.d.ts @@ -5,6 +5,28 @@ // export = rule; // } +declare module 'eslint/lib/rules/arrow-parens' { + import { TSESTree } from '@typescript-eslint/typescript-estree'; + import RuleModule from 'ts-eslint'; + + const rule: RuleModule< + | 'unexpectedParens' + | 'expectedParens' + | 'unexpectedParensInline' + | 'expectedParensBlock', + [ + 'always' | 'as-needed', + { + requireForBlockBody?: boolean; + }? + ], + { + ArrowFunctionExpression(node: TSESTree.ArrowFunctionExpression): void; + } + >; + export = rule; +} + declare module 'eslint/lib/rules/camelcase' { import { TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; @@ -123,6 +145,178 @@ declare module 'eslint/lib/rules/indent' { export = rule; } +declare module 'eslint/lib/rules/no-dupe-args' { + import { TSESTree } from '@typescript-eslint/typescript-estree'; + import RuleModule from 'ts-eslint'; + + const rule: RuleModule< + 'unexpected', + [], + { + FunctionDeclaration(node: TSESTree.FunctionDeclaration): void; + FunctionExpression(node: TSESTree.FunctionExpression): void; + } + >; + export = rule; +} + +declare module 'eslint/lib/rules/no-implicit-globals' { + import { TSESTree } from '@typescript-eslint/typescript-estree'; + import RuleModule from 'ts-eslint'; + + const rule: RuleModule< + never, + [], + { + Program(node: TSESTree.Program): void; + } + >; + export = rule; +} + +declare module 'eslint/lib/rules/no-redeclare' { + import { TSESTree } from '@typescript-eslint/typescript-estree'; + import RuleModule from 'ts-eslint'; + + const rule: RuleModule< + never, + [ + { + builtinGlobals?: boolean; + }? + ], + { + ArrowFunctionExpression(node: TSESTree.ArrowFunctionExpression): void; + } + >; + export = rule; +} + +declare module 'eslint/lib/rules/no-restricted-globals' { + import { TSESTree } from '@typescript-eslint/typescript-estree'; + import RuleModule from 'ts-eslint'; + + const rule: RuleModule< + never, + ( + | string + | { + name: string; + message?: string; + })[], + { + ArrowFunctionExpression(node: TSESTree.ArrowFunctionExpression): void; + } + >; + export = rule; +} + +declare module 'eslint/lib/rules/no-shadow' { + import { TSESTree } from '@typescript-eslint/typescript-estree'; + import RuleModule from 'ts-eslint'; + + const rule: RuleModule< + never, + [ + { + builtinGlobals?: boolean; + hoist: 'all' | 'functions' | 'never'; + allow: string[]; + } + ], + { + ArrowFunctionExpression(node: TSESTree.ArrowFunctionExpression): void; + } + >; + export = rule; +} + +declare module 'eslint/lib/rules/no-undef' { + import { TSESTree } from '@typescript-eslint/typescript-estree'; + import RuleModule from 'ts-eslint'; + + const rule: RuleModule< + 'undef', + [ + { + typeof?: boolean; + } + ], + { + ArrowFunctionExpression(node: TSESTree.ArrowFunctionExpression): void; + } + >; + export = rule; +} + +declare module 'eslint/lib/rules/no-unused-vars' { + import { TSESTree } from '@typescript-eslint/typescript-estree'; + import RuleModule from 'ts-eslint'; + + const rule: RuleModule< + never, + ( + | 'all' + | 'local' + | { + vars?: 'all' | 'local'; + varsIgnorePattern?: string; + args?: 'all' | 'after-used' | 'none'; + ignoreRestSiblings?: boolean; + argsIgnorePattern?: string; + caughtErrors?: 'all' | 'none'; + caughtErrorsIgnorePattern?: string; + })[], + { + ArrowFunctionExpression(node: TSESTree.ArrowFunctionExpression): void; + } + >; + export = rule; +} + +declare module 'eslint/lib/rules/no-use-before-define' { + import { TSESTree } from '@typescript-eslint/typescript-estree'; + import RuleModule from 'ts-eslint'; + + const rule: RuleModule< + never, + ( + | 'nofunc' + | { + functions?: boolean; + classes?: boolean; + variables?: boolean; + })[], + { + ArrowFunctionExpression(node: TSESTree.ArrowFunctionExpression): void; + } + >; + export = rule; +} + +declare module 'eslint/lib/rules/strict' { + import { TSESTree } from '@typescript-eslint/typescript-estree'; + import RuleModule from 'ts-eslint'; + + const rule: RuleModule< + | 'function' + | 'global' + | 'multiple' + | 'never' + | 'unnecessary' + | 'module' + | 'implied' + | 'unnecessaryInClasses' + | 'nonSimpleParameterList' + | 'wrap', + ['never' | 'global' | 'function' | 'safe'], + { + ArrowFunctionExpression(node: TSESTree.ArrowFunctionExpression): void; + } + >; + export = rule; +} + declare module 'eslint/lib/rules/no-useless-constructor' { import { TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; From 90c9dde0b0aaa4ba576ac56464f8c9821cadf9b0 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 4 Feb 2019 20:19:17 -0800 Subject: [PATCH 57/92] no-non-null-assertion --- .../eslint-plugin/src/rules/no-misused-new.ts | 1 + packages/eslint-plugin/src/rules/no-namespace.ts | 1 + .../src/rules/no-non-null-assertion.ts | 16 ++++++++++++---- .../tests/rules/no-non-null-assertion.test.ts | 2 +- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-misused-new.ts b/packages/eslint-plugin/src/rules/no-misused-new.ts index de26df766c31..ad366a7b009d 100644 --- a/packages/eslint-plugin/src/rules/no-misused-new.ts +++ b/packages/eslint-plugin/src/rules/no-misused-new.ts @@ -125,3 +125,4 @@ const rule: RuleModule = { } }; export default rule; +export { Options, MessageIds }; diff --git a/packages/eslint-plugin/src/rules/no-namespace.ts b/packages/eslint-plugin/src/rules/no-namespace.ts index 36d3751af4ac..3d0229f69766 100644 --- a/packages/eslint-plugin/src/rules/no-namespace.ts +++ b/packages/eslint-plugin/src/rules/no-namespace.ts @@ -89,3 +89,4 @@ const rule: RuleModule = { } }; export default rule; +export { Options, MessageIds }; diff --git a/packages/eslint-plugin/src/rules/no-non-null-assertion.ts b/packages/eslint-plugin/src/rules/no-non-null-assertion.ts index f4f4236e29ac..334a140a92b1 100644 --- a/packages/eslint-plugin/src/rules/no-non-null-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-non-null-assertion.ts @@ -3,6 +3,7 @@ * @author Macklin Underdown */ +import { TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; @@ -10,17 +11,23 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -const rule: RuleModule = { +type Options = []; +type MessageIds = 'noNonNull'; + +const rule: RuleModule = { meta: { type: 'problem', docs: { description: 'Disallows non-null assertions using the `!` postfix operator', extraDescription: [util.tslintRule('no-non-null-assertion')], - category: 'TypeScript', + category: 'Stylistic Issues', url: util.metaDocsUrl('no-non-null-assertion'), recommended: 'error' }, + messages: { + noNonNull: 'Forbidden non-null assertion.' + }, schema: [] }, create(context) { @@ -29,13 +36,14 @@ const rule: RuleModule = { //---------------------------------------------------------------------- return { - TSNonNullExpression(node) { + TSNonNullExpression(node: TSESTree.TSNonNullExpression) { context.report({ node, - message: 'Forbidden non-null assertion.' + messageId: 'noNonNull' }); } }; } }; export default rule; +export { Options, MessageIds }; diff --git a/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts index 5840826bd2e0..32a03cd4fff0 100644 --- a/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts @@ -25,7 +25,7 @@ ruleTester.run('no-non-null-assertion', rule, { code: 'const x = null; x!.y;', errors: [ { - message: 'Forbidden non-null assertion.', + messageId: 'noNonNull', line: 1, column: 17 } From 5c95e0edd8a530c6d23925983ebe34e207352781 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 4 Feb 2019 20:24:02 -0800 Subject: [PATCH 58/92] no-object-literal-type-assertion --- .../rules/no-object-literal-type-assertion.ts | 39 +++++++++++-------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts b/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts index 7143f5d74762..cd6efdd91d07 100644 --- a/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts @@ -3,7 +3,7 @@ * @author Armano */ -import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; +import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; @@ -11,20 +11,27 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -const defaultOptions = [ +type Options = [ + { + allowAsParameter?: boolean; + } +]; +type MessageIds = 'unexpectedTypeAssertion'; + +const defaultOptions: Options = [ { allowAsParameter: false } ]; -const rule: RuleModule = { +const rule: RuleModule = { meta: { type: 'problem', docs: { description: 'Forbids an object literal to appear in a type assertion expression', extraDescription: [util.tslintRule('no-object-literal-type-assertion')], - category: 'TypeScript', + category: 'Stylistic Issues', url: util.metaDocsUrl('no-object-literal-type-assertions'), recommended: 'error' }, @@ -56,25 +63,25 @@ const rule: RuleModule = { /** * Check whatever node should be reported - * @param {ASTNode} node the node to be evaluated. + * @param node the node to be evaluated. */ - function checkType(node): boolean { - if (node) { - switch (node.type) { - case AST_NODE_TYPES.TSAnyKeyword: - case AST_NODE_TYPES.TSUnknownKeyword: - return false; - default: - break; - } + function checkType(node: TSESTree.TypeNode): boolean { + switch (node.type) { + case AST_NODE_TYPES.TSAnyKeyword: + case AST_NODE_TYPES.TSUnknownKeyword: + return false; + default: + return true; } - return true; } return { - 'TSTypeAssertion, TSAsExpression'(node) { + 'TSTypeAssertion, TSAsExpression'( + node: TSESTree.TSTypeAssertion | TSESTree.TSAsExpression + ) { if ( allowAsParameter && + node.parent && (node.parent.type === AST_NODE_TYPES.NewExpression || node.parent.type === AST_NODE_TYPES.CallExpression) ) { From 3a8599cdcaaa07883372e1abde9a7fb5f97b2b24 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 4 Feb 2019 20:36:36 -0800 Subject: [PATCH 59/92] no-parameter-properties --- .../src/rules/no-parameter-properties.ts | 53 +++-- .../rules/no-parameter-properties.test.ts | 195 ++++++++++++++---- 2 files changed, 196 insertions(+), 52 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-parameter-properties.ts b/packages/eslint-plugin/src/rules/no-parameter-properties.ts index fa6856de7ce5..02526fe71659 100644 --- a/packages/eslint-plugin/src/rules/no-parameter-properties.ts +++ b/packages/eslint-plugin/src/rules/no-parameter-properties.ts @@ -3,6 +3,7 @@ * @author Patricio Trevino */ +import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; @@ -10,23 +11,42 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -const defaultOptions = [ +type Modifier = + | 'readonly' + | 'private' + | 'protected' + | 'public' + | 'private readonly' + | 'protected readonly' + | 'public readonly'; +type Options = [ + { + allows: Modifier[]; + } +]; +type MessageIds = 'noParamProp'; + +const defaultOptions: Options = [ { allows: [] } ]; -const rule: RuleModule = { +const rule: RuleModule = { meta: { type: 'problem', docs: { description: 'Disallow the use of parameter properties in class constructors.', extraDescription: [util.tslintRule('no-parameter-properties')], - category: 'TypeScript', + category: 'Stylistic Issues', url: util.metaDocsUrl('no-parameter-properties'), recommended: 'error' }, + messages: { + noParamProp: + 'Property {{parameter}} cannot be declared in the constructor.' + }, schema: [ { type: 'object', @@ -61,33 +81,40 @@ const rule: RuleModule = { /** * Gets the modifiers of `node`. - * @param {ASTNode} node the node to be inspected. + * @param node the node to be inspected. */ - function getModifiers(node): string { - const modifiers = []; + function getModifiers(node: TSESTree.TSParameterProperty): Modifier { + const modifiers: Modifier[] = []; - modifiers.push(node.accessibility); - if (node.readonly || node.isReadonly) { + if (node.accessibility) { + modifiers.push(node.accessibility); + } + if (node.readonly) { modifiers.push('readonly'); } - return modifiers.filter(Boolean).join(' '); + return modifiers.filter(Boolean).join(' ') as Modifier; } //---------------------------------------------------------------------- // Public //---------------------------------------------------------------------- return { - TSParameterProperty(node) { + TSParameterProperty(node: TSESTree.TSParameterProperty) { const modifiers = getModifiers(node); if (allows.indexOf(modifiers) === -1) { + const name = + node.parameter.type === AST_NODE_TYPES.Identifier + ? node.parameter.name + : // has to be an Identifier or TSC will throw an error + (node.parameter.left as TSESTree.Identifier).name; + context.report({ node, - message: - 'Property {{parameter}} cannot be declared in the constructor.', + messageId: 'noParamProp', data: { - parameter: node.parameter.name + parameter: name } }); } diff --git a/packages/eslint-plugin/tests/rules/no-parameter-properties.test.ts b/packages/eslint-plugin/tests/rules/no-parameter-properties.test.ts index 0a5922aabbdd..ef63f2bea662 100644 --- a/packages/eslint-plugin/tests/rules/no-parameter-properties.test.ts +++ b/packages/eslint-plugin/tests/rules/no-parameter-properties.test.ts @@ -118,7 +118,10 @@ class Foo { `, errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 3, column: 17 } @@ -132,7 +135,10 @@ class Foo { `, errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 3, column: 17 } @@ -146,7 +152,10 @@ class Foo { `, errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 3, column: 17 } @@ -160,7 +169,10 @@ class Foo { `, errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 3, column: 17 } @@ -174,7 +186,10 @@ class Foo { `, errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 3, column: 17 } @@ -188,7 +203,10 @@ class Foo { `, errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 3, column: 17 } @@ -202,7 +220,10 @@ class Foo { `, errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 3, column: 17 } @@ -216,7 +237,10 @@ class Foo { `, errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 3, column: 17 } @@ -230,12 +254,18 @@ class Foo { `, errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 3, column: 17 }, { - message: 'Property age cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'age' + }, line: 3, column: 39 } @@ -249,12 +279,18 @@ class Foo { `, errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 3, column: 17 }, { - message: 'Property age cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'age' + }, line: 3, column: 41 } @@ -268,12 +304,18 @@ class Foo { `, errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 3, column: 17 }, { - message: 'Property age cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'age' + }, line: 3, column: 38 } @@ -288,7 +330,10 @@ class Foo { `, errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 4, column: 17 } @@ -303,12 +348,18 @@ class Foo { `, errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 3, column: 17 }, { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 4, column: 17 } @@ -323,17 +374,26 @@ class Foo { `, errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 3, column: 17 }, { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 4, column: 17 }, { - message: 'Property age cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'age' + }, line: 4, column: 39 } @@ -348,7 +408,10 @@ class Foo { `, errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 4, column: 17 } @@ -363,12 +426,18 @@ class Foo { `, errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 3, column: 17 }, { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 4, column: 17 } @@ -383,17 +452,26 @@ class Foo { `, errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 3, column: 17 }, { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 4, column: 17 }, { - message: 'Property age cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'age' + }, line: 4, column: 41 } @@ -408,7 +486,10 @@ class Foo { `, errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 4, column: 17 } @@ -423,12 +504,18 @@ class Foo { `, errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 3, column: 17 }, { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 4, column: 17 } @@ -443,17 +530,26 @@ class Foo { `, errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 3, column: 17 }, { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 4, column: 17 }, { - message: 'Property age cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'age' + }, line: 4, column: 38 } @@ -469,7 +565,10 @@ class Foo { options: [{ allows: ['private'] }], errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 3, column: 17 } @@ -484,7 +583,10 @@ class Foo { options: [{ allows: ['readonly'] }], errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 3, column: 17 } @@ -503,7 +605,10 @@ class Foo { ], errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 3, column: 17 } @@ -528,7 +633,10 @@ class Foo { ], errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 3, column: 17 } @@ -543,7 +651,10 @@ class Foo { options: [{ allows: ['readonly', 'private'] }], errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 3, column: 17 } @@ -567,7 +678,10 @@ class Foo { ], errors: [ { - message: 'Property name cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'name' + }, line: 3, column: 17 } @@ -583,7 +697,10 @@ class Foo { options: [{ allows: ['private'] }], errors: [ { - message: 'Property age cannot be declared in the constructor.', + messageId: 'noParamProp', + data: { + parameter: 'age' + }, line: 4, column: 39 } From 0f4253aaf2cc4208f67173faa118fc4af46eca9b Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 4 Feb 2019 21:02:57 -0800 Subject: [PATCH 60/92] no-this-alias --- .../eslint-plugin/src/rules/no-this-alias.ts | 26 ++++++++++++++----- .../tests/rules/no-this-alias.test.ts | 9 ++++--- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-this-alias.ts b/packages/eslint-plugin/src/rules/no-this-alias.ts index 8c3ddcb3535c..bb6419d8bb85 100644 --- a/packages/eslint-plugin/src/rules/no-this-alias.ts +++ b/packages/eslint-plugin/src/rules/no-this-alias.ts @@ -3,7 +3,7 @@ * @author Jed Fox */ -import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; +import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; @@ -11,14 +11,22 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -const defaultOptions = [ +type Options = [ + { + allowDestructuring?: boolean; + allowedNames?: string[]; + } +]; +type MessageIds = 'thisAssignment' | 'thisDestructure'; + +const defaultOptions: Options = [ { allowDestructuring: false, allowedNames: [] as string[] } ]; -const rule: RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { @@ -28,7 +36,6 @@ const rule: RuleModule = { url: util.metaDocsUrl('no-this-alias'), recommended: false }, - fixable: null, schema: [ { type: 'object', @@ -60,14 +67,20 @@ const rule: RuleModule = { )[0]; return { - "VariableDeclarator[init.type='ThisExpression']"(node) { + "VariableDeclarator[init.type='ThisExpression']"( + node: TSESTree.VariableDeclarator + ) { const { id } = node; if (allowDestructuring && id.type !== AST_NODE_TYPES.Identifier) { return; } - if (!allowedNames.includes(id.name)) { + const hasAllowedName = + id.type === AST_NODE_TYPES.Identifier + ? allowedNames!.includes(id.name) + : false; + if (!hasAllowedName) { context.report({ node: id, messageId: @@ -81,3 +94,4 @@ const rule: RuleModule = { } }; export default rule; +export { Options, MessageIds }; diff --git a/packages/eslint-plugin/tests/rules/no-this-alias.test.ts b/packages/eslint-plugin/tests/rules/no-this-alias.test.ts index 6b27dd55bef0..87ff3651e0f9 100644 --- a/packages/eslint-plugin/tests/rules/no-this-alias.test.ts +++ b/packages/eslint-plugin/tests/rules/no-this-alias.test.ts @@ -11,13 +11,16 @@ import rule from '../../src/rules/no-this-alias'; import RuleTester from '../RuleTester'; -const idError = { messageId: 'thisAssignment', type: 'Identifier' }; +const idError = { + messageId: 'thisAssignment' as 'thisAssignment', + type: 'Identifier' +}; const destructureError = { - messageId: 'thisDestructure', + messageId: 'thisDestructure' as 'thisDestructure', type: 'ObjectPattern' }; const arrayDestructureError = { - messageId: 'thisDestructure', + messageId: 'thisDestructure' as 'thisDestructure', type: 'ArrayPattern' }; From 48cb5a1aacddbfb6363278dcaff7080122c3bd8c Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 4 Feb 2019 21:05:43 -0800 Subject: [PATCH 61/92] no-triple-slash-reference --- .../src/rules/no-triple-slash-reference.ts | 44 +++++++++---------- packages/eslint-plugin/typings/ts-eslint.d.ts | 2 +- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts b/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts index 696ed50f07cd..c6fbc469294a 100644 --- a/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts +++ b/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts @@ -5,18 +5,22 @@ import RuleModule from 'ts-eslint'; import * as util from '../util'; +import { TSESTree } from '@typescript-eslint/typescript-estree'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -const rule: RuleModule = { +type Options = []; +type MessageIds = 'tripleSlashReference'; + +const rule: RuleModule = { meta: { type: 'suggestion', docs: { description: 'Disallow `/// ` comments', extraDescription: [util.tslintRule('no-reference')], - category: 'TypeScript', + category: 'Best Practices', url: util.metaDocsUrl('no-triple-slash-reference'), recommended: 'error' }, @@ -34,31 +38,25 @@ const rule: RuleModule = { // Helpers //---------------------------------------------------------------------- - /** - * Checks if property has an accessibility modifier. - * @param {ASTNode} program The node representing a Program. - */ - function checkTripleSlashReference(program): void { - const commentsBefore = sourceCode.getCommentsBefore(program); - - commentsBefore.forEach(comment => { - if (comment.type !== 'Line') { - return; - } - if (referenceRegExp.test(comment.value)) { - context.report({ - node: comment, - messageId: 'tripleSlashReference' - }); - } - }); - } - //---------------------------------------------------------------------- // Public //---------------------------------------------------------------------- return { - Program: checkTripleSlashReference + Program(program: TSESTree.Program): void { + const commentsBefore = sourceCode.getCommentsBefore(program); + + commentsBefore.forEach(comment => { + if (comment.type !== 'Line') { + return; + } + if (referenceRegExp.test(comment.value)) { + context.report({ + node: comment, + messageId: 'tripleSlashReference' + }); + } + }); + } }; } }; diff --git a/packages/eslint-plugin/typings/ts-eslint.d.ts b/packages/eslint-plugin/typings/ts-eslint.d.ts index 7a0d03a2c5cf..d8fc4431feaf 100644 --- a/packages/eslint-plugin/typings/ts-eslint.d.ts +++ b/packages/eslint-plugin/typings/ts-eslint.d.ts @@ -310,7 +310,7 @@ declare module 'ts-eslint' { /** * The Node or AST Token which the report is being attached to */ - node: TSESTree.Node | AST.Token; + node: TSESTree.Node | TSESTree.Comment | AST.Token; /** * An override of the location of the report */ From 077994a730e028506006393e55095150c9c9c60b Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 4 Feb 2019 21:23:49 -0800 Subject: [PATCH 62/92] no-type-alias --- .../eslint-plugin/src/rules/no-type-alias.ts | 129 ++++++++++-------- packages/eslint-plugin/typings/ts-eslint.d.ts | 2 +- 2 files changed, 72 insertions(+), 59 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-type-alias.ts b/packages/eslint-plugin/src/rules/no-type-alias.ts index f24787757f19..1f7d73cbee74 100644 --- a/packages/eslint-plugin/src/rules/no-type-alias.ts +++ b/packages/eslint-plugin/src/rules/no-type-alias.ts @@ -3,15 +3,40 @@ * @author Patricio Trevino */ -import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; +import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/typescript-estree'; +import RuleModule, { ReportDescriptor } from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -const defaultOptions = [ +type Options = [ + { + allowAliases?: + | 'always' + | 'never' + | 'in-unions' + | 'in-intersections' + | 'in-unions-and-intersections'; + allowCallbacks?: 'always' | 'never'; + allowLiterals?: + | 'always' + | 'never' + | 'in-unions' + | 'in-intersections' + | 'in-unions-and-intersections'; + allowMappedTypes?: + | 'always' + | 'never' + | 'in-unions' + | 'in-intersections' + | 'in-unions-and-intersections'; + } +]; +type MessageIds = 'noTypeAlias' | 'noCompositionAlias'; + +const defaultOptions: Options = [ { allowAliases: 'never', allowCallbacks: 'never', @@ -20,13 +45,13 @@ const defaultOptions = [ } ]; -const rule: RuleModule = { +const rule: RuleModule = { meta: { type: 'suggestion', docs: { description: 'Disallow the use of type aliases', extraDescription: [util.tslintRule('interface-over-type-literal')], - category: 'TypeScript', + category: 'Stylistic Issues', url: util.metaDocsUrl('no-type-alias'), recommended: false }, @@ -94,22 +119,17 @@ const rule: RuleModule = { 'in-intersections', 'in-unions-and-intersections' ]; - const aliasTypes = [ - 'TSLastTypeNode', - 'TSArrayType', - 'TSTypeReference', - 'TSLiteralType' - ]; + const aliasTypes = ['TSArrayType', 'TSTypeReference', 'TSLiteralType']; //---------------------------------------------------------------------- // Helpers //---------------------------------------------------------------------- + type CompositionType = TSESTree.TSUnionType | TSESTree.TSIntersectionType; /** * Determines if the given node is a union or an intersection. - * @param {TSNode} node the node to be evaluated. */ - function isComposition(node): boolean { + function isComposition(node: TSESTree.TypeNode): node is CompositionType { return ( node && (node.type === AST_NODE_TYPES.TSUnionType || @@ -140,9 +160,11 @@ const rule: RuleModule = { /** * Determines if the given node is an alias type (keywords, arrays, type references and constants). - * @param {TSNode} node the node to be evaluated. + * @param node the node to be evaluated. */ - function isAlias(node): boolean { + function isAlias( + node: TSESTree.Node + ): boolean /* not worth enumerating the ~25 individual types here */ { return ( node && (/Keyword$/.test(node.type) || aliasTypes.indexOf(node.type) > -1) @@ -151,42 +173,42 @@ const rule: RuleModule = { /** * Determines if the given node is a callback type. - * @param {TSNode} node the node to be evaluated. + * @param node the node to be evaluated. */ - function isCallback(node): boolean { + function isCallback(node: TSESTree.Node): node is TSESTree.TSFunctionType { return node && node.type === AST_NODE_TYPES.TSFunctionType; } /** * Determines if the given node is a literal type (objects). - * @param {TSNode} node the node to be evaluated. + * @param node the node to be evaluated. */ - function isLiteral(node): boolean { + function isLiteral(node: TSESTree.Node): node is TSESTree.TSTypeLiteral { return node && node.type === AST_NODE_TYPES.TSTypeLiteral; } /** * Determines if the given node is a mapped type. - * @param {TSNode} node the node to be evaluated. + * @param node the node to be evaluated. */ - function isMappedType(node): boolean { + function isMappedType(node: TSESTree.Node): node is TSESTree.TSMappedType { return node && node.type === AST_NODE_TYPES.TSMappedType; } /** * Gets the message to be displayed based on the node type and whether the node is a top level declaration. - * @param {ASTNode} node the location + * @param node the location * @param compositionType the type of composition this alias is part of (undefined if not * part of a composition) * @param isRoot a flag indicating we are dealing with the top level declaration. * @param type the kind of type alias being validated. */ function getMessage( - node, + node: TSESTree.Node, compositionType: string | undefined, isRoot: boolean, type?: string - ): Rule.ReportDescriptor { + ): ReportDescriptor { if (isRoot) { return { node, @@ -212,26 +234,17 @@ const rule: RuleModule = { /** * Validates the node looking for aliases, callbacks and literals. - * @param {TSNode} node the node to be validated. + * @param node the node to be validated. * @param isTopLevel a flag indicating this is the top level node. * @param compositionType the type of composition this alias is part of (undefined if not * part of a composition) */ function validateTypeAliases( - node, + node: TSESTree.Node, isTopLevel: boolean, compositionType?: string ): void { - if (isAlias(node)) { - if ( - allowAliases === 'never' || - !isSupportedComposition(isTopLevel, compositionType, allowAliases) - ) { - context.report( - getMessage(node, compositionType, isTopLevel, 'aliases') - ); - } - } else if (isCallback(node)) { + if (isCallback(node)) { if (allowCallbacks === 'never') { context.report( getMessage(node, compositionType, isTopLevel, 'callbacks') @@ -240,7 +253,7 @@ const rule: RuleModule = { } else if (isLiteral(node)) { if ( allowLiterals === 'never' || - !isSupportedComposition(isTopLevel, compositionType, allowLiterals) + !isSupportedComposition(isTopLevel, compositionType, allowLiterals!) ) { context.report( getMessage(node, compositionType, isTopLevel, 'literals') @@ -249,12 +262,25 @@ const rule: RuleModule = { } else if (isMappedType(node)) { if ( allowMappedTypes === 'never' || - !isSupportedComposition(isTopLevel, compositionType, allowMappedTypes) + !isSupportedComposition( + isTopLevel, + compositionType, + allowMappedTypes! + ) ) { context.report( getMessage(node, compositionType, isTopLevel, 'mapped types') ); } + } else if (isAlias(node)) { + if ( + allowAliases === 'never' || + !isSupportedComposition(isTopLevel, compositionType, allowAliases!) + ) { + context.report( + getMessage(node, compositionType, isTopLevel, 'aliases') + ); + } } else { context.report(getMessage(node, compositionType, isTopLevel)); } @@ -262,11 +288,8 @@ const rule: RuleModule = { /** * Validates compositions (unions and/or intersections). - * @param {TSNode} node the node to be validated. - * @returns {void} - * @private */ - function validateCompositions(node) { + function validateCompositions(node: CompositionType): void { node.types.forEach(type => { if (isComposition(type)) { validateCompositions(type); @@ -276,26 +299,16 @@ const rule: RuleModule = { }); } - /** - * Validates the node looking for compositions, aliases, callbacks and literals. - * @param {TSNode} node the node to be validated. - * @param isTopLevel a flag indicating this is the top level node. - * @private - */ - function validateNode(node): void { - if (isComposition(node)) { - validateCompositions(node); - } else { - validateTypeAliases(node, true); - } - } - //---------------------------------------------------------------------- // Public //---------------------------------------------------------------------- return { - TSTypeAliasDeclaration(node) { - validateNode(node.typeAnnotation); + TSTypeAliasDeclaration(node: TSESTree.TSTypeAliasDeclaration) { + if (isComposition(node.typeAnnotation)) { + validateCompositions(node.typeAnnotation); + } else { + validateTypeAliases(node.typeAnnotation, true); + } } }; } diff --git a/packages/eslint-plugin/typings/ts-eslint.d.ts b/packages/eslint-plugin/typings/ts-eslint.d.ts index d8fc4431feaf..79f1ac4609d4 100644 --- a/packages/eslint-plugin/typings/ts-eslint.d.ts +++ b/packages/eslint-plugin/typings/ts-eslint.d.ts @@ -411,6 +411,6 @@ declare module 'ts-eslint' { //#endregion Rule - export { RuleContext, ReportFixFunction }; + export { RuleContext, ReportFixFunction, ReportDescriptor }; export default RuleModule; } From 06341494dfc4799e57ff9f225507c31bbdbf795a Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 4 Feb 2019 21:31:53 -0800 Subject: [PATCH 63/92] no-unused-vars --- .../eslint-plugin/src/rules/no-unused-vars.ts | 26 +++--- .../tests/rules/no-unused-vars.test.ts | 79 ++++++++++--------- 2 files changed, 60 insertions(+), 45 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-unused-vars.ts b/packages/eslint-plugin/src/rules/no-unused-vars.ts index 069aa8ada739..0ad34e3e01e4 100644 --- a/packages/eslint-plugin/src/rules/no-unused-vars.ts +++ b/packages/eslint-plugin/src/rules/no-unused-vars.ts @@ -7,12 +7,19 @@ import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import baseRule from 'eslint/lib/rules/no-unused-vars'; import * as util from '../util'; +import { + InferMessageIdsTypeFromRule, + InferOptionsTypeFromRule +} from '../tsestree-utils'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -const rule: RuleModule = Object.assign({}, baseRule, { +type Options = InferOptionsTypeFromRule; +type MessageIds = InferMessageIdsTypeFromRule; + +const rule: RuleModule = { meta: { type: 'problem', docs: { @@ -49,7 +56,7 @@ const rule: RuleModule = Object.assign({}, baseRule, { * Mark heritage clause as used * @param node The node currently being traversed */ - function markHeritageAsUsed(node): void { + function markHeritageAsUsed(node: TSESTree.Expression): void { switch (node.type) { case AST_NODE_TYPES.Identifier: context.markVariableAsUsed(node.name); @@ -69,27 +76,27 @@ const rule: RuleModule = Object.assign({}, baseRule, { return Object.assign({}, rules, { "FunctionDeclaration Identifier[name='this']": markThisParameterAsUsed, "FunctionExpression Identifier[name='this']": markThisParameterAsUsed, - 'TSTypeReference Identifier'(node) { + 'TSTypeReference Identifier'(node: TSESTree.Identifier) { context.markVariableAsUsed(node.name); }, - TSInterfaceHeritage(node) { + TSInterfaceHeritage(node: TSESTree.TSInterfaceHeritage) { if (node.expression) { markHeritageAsUsed(node.expression); } }, - TSClassImplements(node) { + TSClassImplements(node: TSESTree.TSClassImplements) { if (node.expression) { markHeritageAsUsed(node.expression); } }, - 'TSParameterProperty Identifier'(node) { + 'TSParameterProperty Identifier'(node: TSESTree.Identifier) { // just assume parameter properties are used context.markVariableAsUsed(node.name); }, - 'TSEnumMember Identifier'(node) { + 'TSEnumMember Identifier'(node: TSESTree.Identifier) { context.markVariableAsUsed(node.name); }, - '*[declare=true] Identifier'(node) { + '*[declare=true] Identifier'(node: TSESTree.Identifier) { context.markVariableAsUsed(node.name); const scope = context.getScope(); const { variableScope } = scope; @@ -100,5 +107,6 @@ const rule: RuleModule = Object.assign({}, baseRule, { } }); } -}); +}; export default rule; +export { Options, MessageIds }; diff --git a/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts b/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts index 0458c7c7009d..2f52aa3a4b0b 100644 --- a/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts @@ -23,6 +23,13 @@ const ruleTester = new RuleTester({ // Tests //------------------------------------------------------------------------------ +// the base rule doesn't have messageIds +function error( + messages: { message: string; line: number; column: number }[] +): any[] { + return messages; +} + ruleTester.run('no-unused-vars', rule, { valid: [ ` @@ -592,13 +599,13 @@ export function Foo() { import { ClassDecoratorFactory } from 'decorators'; export class Foo {} `, - errors: [ + errors: error([ { message: "'ClassDecoratorFactory' is defined but never used.", line: 2, column: 10 } - ] + ]) }, { code: ` @@ -606,13 +613,13 @@ import { Foo, Bar } from 'foo'; function baz() {} baz() `, - errors: [ + errors: error([ { message: "'Foo' is defined but never used.", line: 2, column: 10 } - ] + ]) }, { code: ` @@ -620,13 +627,13 @@ import { Nullable } from 'nullable'; const a: string = 'hello'; console.log(a); `, - errors: [ + errors: error([ { message: "'Nullable' is defined but never used.", line: 2, column: 10 } - ] + ]) }, { code: ` @@ -635,13 +642,13 @@ import { SomeOther } from 'other'; const a: Nullable = 'hello'; console.log(a); `, - errors: [ + errors: error([ { message: "'SomeOther' is defined but never used.", line: 3, column: 10 } - ] + ]) }, { @@ -653,13 +660,13 @@ class A { } new A(); `, - errors: [ + errors: error([ { message: "'Another' is defined but never used.", line: 3, column: 10 } - ] + ]) }, { code: ` @@ -670,13 +677,13 @@ class A { } new A(); `, - errors: [ + errors: error([ { message: "'Another' is defined but never used.", line: 3, column: 10 } - ] + ]) }, { code: ` @@ -687,13 +694,13 @@ class A { } new A(); `, - errors: [ + errors: error([ { message: "'Another' is defined but never used.", line: 3, column: 10 } - ] + ]) }, { code: ` @@ -703,13 +710,13 @@ interface A { do(a: Nullable); } `, - errors: [ + errors: error([ { message: "'Another' is defined but never used.", line: 3, column: 10 } - ] + ]) }, { code: ` @@ -719,13 +726,13 @@ interface A { other: Nullable; } `, - errors: [ + errors: error([ { message: "'Another' is defined but never used.", line: 3, column: 10 } - ] + ]) }, { code: ` @@ -733,13 +740,13 @@ import { Nullable } from 'nullable'; function foo(a: string) { console.log(a); } foo(); `, - errors: [ + errors: error([ { message: "'Nullable' is defined but never used.", line: 2, column: 10 } - ] + ]) }, { code: ` @@ -747,13 +754,13 @@ import { Nullable } from 'nullable'; function foo(): string | null { return null; } foo(); `, - errors: [ + errors: error([ { message: "'Nullable' is defined but never used.", line: 2, column: 10 } - ] + ]) }, { code: ` @@ -765,13 +772,13 @@ class A extends Nullable { } new A(); `, - errors: [ + errors: error([ { message: "'SomeOther' is defined but never used.", line: 3, column: 10 } - ] + ]) }, { code: ` @@ -783,13 +790,13 @@ abstract class A extends Nullable { } new A(); `, - errors: [ + errors: error([ { message: "'SomeOther' is defined but never used.", line: 3, column: 10 } - ] + ]) }, { code: ` @@ -798,13 +805,13 @@ enum FormFieldIds { EMAIL = 'email', } `, - errors: [ + errors: error([ { message: "'FormFieldIds' is defined but never used.", line: 2, column: 6 } - ] + ]) }, { code: ` @@ -812,13 +819,13 @@ import test from 'test'; import baz from 'baz'; export interface Bar extends baz.test {} `, - errors: [ + errors: error([ { message: "'test' is defined but never used.", line: 2, column: 8 } - ] + ]) }, { code: ` @@ -826,13 +833,13 @@ import test from 'test'; import baz from 'baz'; export interface Bar extends baz().test {} `, - errors: [ + errors: error([ { message: "'test' is defined but never used.", line: 2, column: 8 } - ] + ]) }, { code: ` @@ -840,13 +847,13 @@ import test from 'test'; import baz from 'baz'; export class Bar implements baz.test {} `, - errors: [ + errors: error([ { message: "'test' is defined but never used.", line: 2, column: 8 } - ] + ]) }, { code: ` @@ -854,13 +861,13 @@ import test from 'test'; import baz from 'baz'; export class Bar implements baz().test {} `, - errors: [ + errors: error([ { message: "'test' is defined but never used.", line: 2, column: 8 } - ] + ]) } ] }); From 0d3b2b82e3748e8cfef7231cc3b0600d40715118 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 4 Feb 2019 22:08:09 -0800 Subject: [PATCH 64/92] no-use-before-define --- .../src/rules/no-use-before-define.ts | 97 ++--- packages/eslint-plugin/tests/RuleTester.ts | 3 +- .../tests/rules/no-use-before-define.test.ts | 369 ++++++++++++------ packages/eslint-plugin/typings/ts-eslint.d.ts | 106 ++++- 4 files changed, 387 insertions(+), 188 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-use-before-define.ts b/packages/eslint-plugin/src/rules/no-use-before-define.ts index da5550b4998e..e48d76f45a18 100644 --- a/packages/eslint-plugin/src/rules/no-use-before-define.ts +++ b/packages/eslint-plugin/src/rules/no-use-before-define.ts @@ -1,13 +1,11 @@ /** * @fileoverview Rule to flag use of variables before they are defined - * @copyright ESLint - * @see https://github.com/eslint/eslint/blob/a113cd3/lib/rules/no-use-before-define.js * @author Ilya Volodin * @author Jed Fox */ -import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; -import { Rule, Scope } from 'eslint'; +import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/typescript-estree'; +import RuleModule, { Scope } from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ @@ -15,21 +13,11 @@ import * as util from '../util'; //------------------------------------------------------------------------------ const SENTINEL_TYPE = /^(?:(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|CatchClause|ImportDeclaration|ExportNamedDeclaration)$/; -const FOR_IN_OF_TYPE = /^For(?:In|Of)Statement$/; - -interface Options { - functions?: boolean; - classes?: boolean; - variables?: boolean; - typedefs?: boolean; -} /** * Parses a given value as options. - * - * @param {any} options - A value to parse. */ -function parseOptions(options: string | Options | null): Options { +function parseOptions(options: string | Config | null): Required { let functions = true; let classes = true; let variables = true; @@ -49,7 +37,6 @@ function parseOptions(options: string | Options | null): Options { /** * Checks whether or not a given scope is a top level scope. - * @param scope - a scope to check */ function isTopLevelScope(scope: Scope.Scope): boolean { return scope.type === 'module' || scope.type === 'global'; @@ -57,22 +44,19 @@ function isTopLevelScope(scope: Scope.Scope): boolean { /** * Checks whether or not a given variable is a function declaration. - * @param variable - A variable to check. */ function isFunction(variable: Scope.Variable): boolean { - return variable.defs[0].type === AST_NODE_TYPES.FunctionName; + return variable.defs[0].type === 'FunctionName'; } /** * Checks whether or not a given variable is a class declaration in an upper function scope. - * @param variable - A variable to check. - * @param reference - A reference to check. */ function isOuterClass( variable: Scope.Variable, reference: Scope.Reference ): boolean { - if (variable.defs[0].type !== AST_NODE_TYPES.ClassName) { + if (variable.defs[0].type !== 'ClassName') { return false; } @@ -88,14 +72,12 @@ function isOuterClass( /** * Checks whether or not a given variable is a variable declaration in an upper function scope. - * @param variable - A variable to check. - * @param reference - A reference to check. */ function isOuterVariable( variable: Scope.Variable, reference: Scope.Reference ): boolean { - if (variable.defs[0].type !== AST_NODE_TYPES.Variable) { + if (variable.defs[0].type !== 'Variable') { return false; } @@ -109,42 +91,25 @@ function isOuterVariable( return true; } -/** - * Checks whether or not a given variable is a type declaration. - * @param variable - A type to check. - */ -function isType(variable: Scope.Variable): boolean { - const def = variable.defs[0]; - return !!( - def.type === AST_NODE_TYPES.Variable && - def.parent && - def.parent.kind === 'type' - ); -} - /** * Checks whether or not a given location is inside of the range of a given node. - * - * @param {ASTNode} node - An node to check. - * @param location - A location to check. */ -function isInRange(node, location: number): boolean { - return node && node.range[0] <= location && location <= node.range[1]; +function isInRange( + node: TSESTree.Expression | null | undefined, + location: number +): boolean { + return !!node && node.range[0] <= location && location <= node.range[1]; } /** * Checks whether or not a given reference is inside of the initializers of a given variable. * - * This returns `true` in the following cases: - * - * var a = a - * var [a = a] = list - * var {a = a} = obj - * for (var a in a) {} - * for (var a of a) {} - * - * @param variable - A variable to check. - * @param reference - A reference to check. + * @returns `true` in the following cases: + * - var a = a + * - var [a = a] = list + * - var {a = a} = obj + * - for (var a in a) {} + * - for (var a of a) {} */ function isInInitializer( variable: Scope.Variable, @@ -163,7 +128,10 @@ function isInInitializer( return true; } if ( - FOR_IN_OF_TYPE.test(node.parent.parent.type) && + node.parent && + node.parent.parent && + (node.parent.parent.type === AST_NODE_TYPES.ForInStatement || + node.parent.parent.type === AST_NODE_TYPES.ForOfStatement) && isInRange(node.parent.parent.right, location) ) { return true; @@ -187,7 +155,16 @@ function isInInitializer( // Rule Definition //------------------------------------------------------------------------------ -const defaultOptions = [ +interface Config { + functions?: boolean; + classes?: boolean; + variables?: boolean; + typedefs?: boolean; +} +type Options = [Config]; +type MessageIds = 'noUseBeforeDefine'; + +const defaultOptions: Options = [ { functions: true, classes: true, @@ -196,7 +173,7 @@ const defaultOptions = [ } ]; -const rule: RuleModule = { +const rule: RuleModule = { meta: { type: 'problem', docs: { @@ -205,6 +182,9 @@ const rule: RuleModule = { url: util.metaDocsUrl('no-use-before-define'), recommended: 'error' }, + messages: { + noUseBeforeDefine: "'{{name}}' was used before it was defined." + }, schema: [ { oneOf: [ @@ -246,9 +226,6 @@ const rule: RuleModule = { if (isOuterClass(variable, reference)) { return !!options.classes; } - if (isType(variable) && !options.typedefs) { - return false; - } if (isOuterVariable(variable, reference)) { return !!options.variables; } @@ -257,7 +234,6 @@ const rule: RuleModule = { /** * Finds and validates all variables in a given scope. - * @param {Scope} scope The scope object. */ function findVariablesInScope(scope: Scope.Scope): void { scope.references.forEach(reference => { @@ -283,7 +259,7 @@ const rule: RuleModule = { // Reports. context.report({ node: reference.identifier, - message: "'{{name}}' was used before it was defined.", + messageId: 'noUseBeforeDefine', data: reference.identifier }); }); @@ -299,3 +275,4 @@ const rule: RuleModule = { } }; export default rule; +export { Options, MessageIds }; diff --git a/packages/eslint-plugin/tests/RuleTester.ts b/packages/eslint-plugin/tests/RuleTester.ts index 1027b710ca00..1e52496afad7 100644 --- a/packages/eslint-plugin/tests/RuleTester.ts +++ b/packages/eslint-plugin/tests/RuleTester.ts @@ -1,3 +1,4 @@ +import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; import { RuleTester, Linter } from 'eslint'; import RuleModule from 'ts-eslint'; @@ -20,7 +21,7 @@ interface InvalidTestCase interface TestCaseError { messageId: TMessageIds; data?: Record; - // type?: string; + type?: AST_NODE_TYPES; line?: number; column?: number; // endLine?: number; diff --git a/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts b/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts index bfef6af5d520..13dd9f329194 100644 --- a/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts +++ b/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts @@ -8,8 +8,9 @@ // Requirements //------------------------------------------------------------------------------ -import rule from '../../src/rules/no-use-before-define'; +import rule, { Options } from '../../src/rules/no-use-before-define'; import RuleTester from '../RuleTester'; +import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; //------------------------------------------------------------------------------ // Tests @@ -19,8 +20,16 @@ const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); +const parserOptions = { ecmaVersion: 6 as 6 }; + ruleTester.run('no-use-before-define', rule, { valid: [ + 'type foo = 1; const x: foo = 1;', + 'type foo = 1; type bar = foo;', + ` +interface Foo {} +const x: Foo = {}; + `, 'var a=10; alert(a);', 'function b(a) { alert(a); }', 'Object.hasOwnProperty.call(a);', @@ -32,11 +41,11 @@ ruleTester.run('no-use-before-define', rule, { a(); function a() { alert(arguments); } `, - options: ['nofunc'] + options: ['nofunc'] as Options }, { code: '(() => { var a = 42; alert(a); })();', - parserOptions: { ecmaVersion: 6 } + parserOptions }, ` a(); @@ -49,11 +58,11 @@ try { class A {} new A(); `, - parserOptions: { ecmaVersion: 6 } + parserOptions }, 'var a = 0, b = a;', - { code: 'var {a = 0, b = a} = {};', parserOptions: { ecmaVersion: 6 } }, - { code: 'var [a = 0, b = a] = {};', parserOptions: { ecmaVersion: 6 } }, + { code: 'var {a = 0, b = a} = {};', parserOptions }, + { code: 'var [a = 0, b = a] = {};', parserOptions }, ` function foo() { foo(); @@ -73,7 +82,7 @@ for (a in a) {} var a; for (a of a) {} `, - parserOptions: { ecmaVersion: 6 } + parserOptions }, // Block-level bindings @@ -85,7 +94,7 @@ a(); function a() {} } `, - parserOptions: { ecmaVersion: 6 } + parserOptions }, { code: ` @@ -95,8 +104,8 @@ a(); function a() {} } `, - options: ['nofunc'], - parserOptions: { ecmaVersion: 6 } + options: ['nofunc'] as Options, + parserOptions }, { code: ` @@ -109,7 +118,7 @@ switch (foo) { } } `, - parserOptions: { ecmaVersion: 6 } + parserOptions }, { code: ` @@ -118,7 +127,7 @@ a(); let a = function () {}; } `, - parserOptions: { ecmaVersion: 6 } + parserOptions }, // object style options @@ -140,7 +149,7 @@ function a() { } `, options: [{ functions: false }], - parserOptions: { ecmaVersion: 6 } + parserOptions }, { code: ` @@ -150,7 +159,7 @@ function foo() { class A {}; `, options: [{ classes: false }], - parserOptions: { ecmaVersion: 6 } + parserOptions }, // "variables" option @@ -169,7 +178,7 @@ var foo = () => bar; var bar; `, options: [{ variables: false }], - parserOptions: { ecmaVersion: 6 } + parserOptions }, // "typedefs" option @@ -188,7 +197,7 @@ var alias = Test; class Test {} `, - parserOptions: { ecmaVersion: 6 }, + parserOptions, options: [{ classes: false }] }, { @@ -227,11 +236,14 @@ export namespace Third { a++; var a=19; `, - parserOptions: { sourceType: 'module' }, + parserOptions: { sourceType: 'module' as 'module' }, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -240,11 +252,14 @@ var a=19; a++; var a=19; `, - parserOptions: { parserOptions: { ecmaVersion: 6 } }, + parserOptions: { parserOptions }, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -255,8 +270,11 @@ var a=19; `, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -267,8 +285,11 @@ var a=function() {}; `, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -279,8 +300,11 @@ var a=[1,3]; `, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -295,12 +319,18 @@ function a() { `, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier }, { - message: "'b' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'b' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -310,11 +340,14 @@ a(); var a=function() {}; `, - options: ['nofunc'], + options: ['nofunc'] as Options, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -327,11 +360,14 @@ var a=function() {}; } )(); `, - parserOptions: { ecmaVersion: 6 }, + parserOptions, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -342,11 +378,14 @@ var a=function() {}; )(); function a() { } `, - parserOptions: { ecmaVersion: 6 }, + parserOptions, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -361,8 +400,11 @@ a(); parser: 'espree', errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -377,8 +419,11 @@ try { `, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -387,11 +432,14 @@ try { var f = () => a; var a; `, - parserOptions: { ecmaVersion: 6 }, + parserOptions, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -400,11 +448,14 @@ var a; new A(); class A {}; `, - parserOptions: { ecmaVersion: 6 }, + parserOptions, errors: [ { - message: "'A' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'A' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -415,11 +466,14 @@ function foo() { } class A {}; `, - parserOptions: { ecmaVersion: 6 }, + parserOptions, errors: [ { - message: "'A' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'A' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -428,11 +482,14 @@ class A {}; new A(); var A = class {}; `, - parserOptions: { ecmaVersion: 6 }, + parserOptions, errors: [ { - message: "'A' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'A' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -443,11 +500,14 @@ function foo() { } var A = class {}; `, - parserOptions: { ecmaVersion: 6 }, + parserOptions, errors: [ { - message: "'A' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'A' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -460,11 +520,14 @@ a++; var a; } `, - parserOptions: { ecmaVersion: 6 }, + parserOptions, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -476,11 +539,14 @@ a++; function a() {} } `, - parserOptions: { ecmaVersion: 6 }, + parserOptions, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -491,11 +557,14 @@ a++; let a = 1 } `, - parserOptions: { ecmaVersion: 6 }, + parserOptions, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -508,11 +577,14 @@ switch (foo) { let a; } `, - parserOptions: { ecmaVersion: 6 }, + parserOptions, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -525,11 +597,14 @@ if (true) { let a; } `, - parserOptions: { ecmaVersion: 6 }, + parserOptions, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -543,8 +618,11 @@ var a=function() {}; options: [{ functions: false, classes: false }], errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -553,12 +631,15 @@ var a=function() {}; new A(); var A = class {}; `, - options: [{ classes: false }], - parserOptions: { ecmaVersion: 6 }, + options: [{ classes: false }] as Options, + parserOptions, errors: [ { - message: "'A' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'A' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -569,12 +650,15 @@ function foo() { } var A = class {}; `, - options: [{ classes: false }], - parserOptions: { ecmaVersion: 6 }, + options: [{ classes: false }] as Options, + parserOptions, errors: [ { - message: "'A' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'A' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -584,98 +668,128 @@ var A = class {}; code: 'var a = a;', errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, { code: 'let a = a + b;', - parserOptions: { ecmaVersion: 6 }, + parserOptions, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, { code: 'const a = foo(a);', - parserOptions: { ecmaVersion: 6 }, + parserOptions, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, { code: 'function foo(a = a) {}', - parserOptions: { ecmaVersion: 6 }, + parserOptions, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, { code: 'var {a = a} = [];', - parserOptions: { ecmaVersion: 6 }, + parserOptions, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, { code: 'var [a = a] = [];', - parserOptions: { ecmaVersion: 6 }, + parserOptions, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, { code: 'var {b = a, a} = {};', - parserOptions: { ecmaVersion: 6 }, + parserOptions, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, { code: 'var [b = a, a] = {};', - parserOptions: { ecmaVersion: 6 }, + parserOptions, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, { code: 'var {a = 0} = a;', - parserOptions: { ecmaVersion: 6 }, + parserOptions, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, { code: 'var [a = 0] = a;', - parserOptions: { ecmaVersion: 6 }, + parserOptions, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -683,18 +797,24 @@ var A = class {}; code: 'for (var a in a) {}', errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, { code: 'for (var a of a) {}', - parserOptions: { ecmaVersion: 6 }, + parserOptions, errors: [ { - message: "'a' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'a' + }, + type: AST_NODE_TYPES.Identifier } ] }, @@ -708,12 +828,15 @@ function foo() { } var bar; `, - parserOptions: { ecmaVersion: 6 }, - options: [{ variables: false }], + parserOptions, + options: [{ variables: false }] as Options, errors: [ { - message: "'bar' was used before it was defined.", - type: 'Identifier' + messageId: 'noUseBeforeDefine', + data: { + name: 'bar' + }, + type: AST_NODE_TYPES.Identifier } ] } diff --git a/packages/eslint-plugin/typings/ts-eslint.d.ts b/packages/eslint-plugin/typings/ts-eslint.d.ts index 79f1ac4609d4..c7ce1e4fac9a 100644 --- a/packages/eslint-plugin/typings/ts-eslint.d.ts +++ b/packages/eslint-plugin/typings/ts-eslint.d.ts @@ -10,12 +10,11 @@ The def is wrapped up in a fake module so that it can be used in eslint-rules.d. declare module 'ts-eslint' { import { TSESTree } from '@typescript-eslint/typescript-estree'; import { ParserServices } from '@typescript-eslint/parser'; - import { AST, Linter, Scope } from 'eslint'; + import { AST, Linter } from 'eslint'; import { JSONSchema4 } from 'json-schema'; //#region SourceCode - // eslint-disable-next-line @typescript-eslint/no-namespace namespace SourceCode { export interface Config { text: string; @@ -52,7 +51,6 @@ declare module 'ts-eslint' { }; } - // eslint-disable-next-line no-redeclare class SourceCode { text: string; ast: AST.Program; @@ -411,6 +409,106 @@ declare module 'ts-eslint' { //#endregion Rule - export { RuleContext, ReportFixFunction, ReportDescriptor }; + namespace Scope { + interface ScopeManager { + scopes: Scope[]; + globalScope: Scope | null; + + acquire(node: TSESTree.Node, inner?: boolean): Scope | null; + + getDeclaredVariables(node: TSESTree.Node): Variable[]; + } + + interface Reference { + identifier: TSESTree.Identifier; + from: Scope; + resolved: Variable | null; + writeExpr: TSESTree.Node | null; + init: boolean; + + isWrite(): boolean; + + isRead(): boolean; + + isWriteOnly(): boolean; + + isReadOnly(): boolean; + + isReadWrite(): boolean; + } + + interface Variable { + name: string; + identifiers: TSESTree.Identifier[]; + references: Reference[]; + defs: Definition[]; + scope: Scope; + } + + interface Scope { + type: + | 'block' + | 'catch' + | 'class' + | 'for' + | 'function' + | 'function-expression-name' + | 'global' + | 'module' + | 'switch' + | 'with' + | 'TDZ'; + isStrict: boolean; + upper: Scope | null; + childScopes: Scope[]; + variableScope: Scope; + block: TSESTree.Node; + variables: Variable[]; + set: Map; + references: Reference[]; + through: Reference[]; + functionExpressionScope: boolean; + } + + type DefinitionType = + | { type: 'CatchClause'; node: TSESTree.CatchClause; parent: null } + | { + type: 'ClassName'; + node: TSESTree.ClassDeclaration | TSESTree.ClassExpression; + parent: null; + } + | { + type: 'FunctionName'; + node: TSESTree.FunctionDeclaration | TSESTree.FunctionExpression; + parent: null; + } + | { type: 'ImplicitGlobalVariable'; node: TSESTree.Program; parent: null } + | { + type: 'ImportBinding'; + node: + | TSESTree.ImportSpecifier + | TSESTree.ImportDefaultSpecifier + | TSESTree.ImportNamespaceSpecifier; + parent: TSESTree.ImportDeclaration; + } + | { + type: 'Parameter'; + node: + | TSESTree.FunctionDeclaration + | TSESTree.FunctionExpression + | TSESTree.ArrowFunctionExpression; + parent: null; + } + | { type: 'TDZ'; node: any; parent: null } + | { + type: 'Variable'; + node: TSESTree.VariableDeclarator; + parent: TSESTree.VariableDeclaration; + }; + + type Definition = DefinitionType & { name: TSESTree.Identifier }; + } + + export { RuleContext, ReportFixFunction, ReportDescriptor, Scope }; export default RuleModule; } From d24d61dec535579f202e035e899715ee0577c553 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 4 Feb 2019 22:14:29 -0800 Subject: [PATCH 65/92] no-useless-constructor --- packages/eslint-plugin/src/rules/no-useless-constructor.ts | 3 ++- ...o-useless-constructor.ts => no-useless-constructor.test.ts} | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) rename packages/eslint-plugin/tests/rules/{no-useless-constructor.ts => no-useless-constructor.test.ts} (98%) diff --git a/packages/eslint-plugin/src/rules/no-useless-constructor.ts b/packages/eslint-plugin/src/rules/no-useless-constructor.ts index 19cc5de8cb98..c7426aab428f 100644 --- a/packages/eslint-plugin/src/rules/no-useless-constructor.ts +++ b/packages/eslint-plugin/src/rules/no-useless-constructor.ts @@ -31,7 +31,8 @@ function checkAccessibility(node: TSESTree.MethodDefinition): boolean { node.parent && node.parent.type === AST_NODE_TYPES.ClassBody && node.parent.parent && - 'superClass' in node.parent.parent + 'superClass' in node.parent.parent && + node.parent.parent.superClass ) { return false; } diff --git a/packages/eslint-plugin/tests/rules/no-useless-constructor.ts b/packages/eslint-plugin/tests/rules/no-useless-constructor.test.ts similarity index 98% rename from packages/eslint-plugin/tests/rules/no-useless-constructor.ts rename to packages/eslint-plugin/tests/rules/no-useless-constructor.test.ts index fb82cd639dce..6ece0d970ae5 100644 --- a/packages/eslint-plugin/tests/rules/no-useless-constructor.ts +++ b/packages/eslint-plugin/tests/rules/no-useless-constructor.test.ts @@ -4,7 +4,7 @@ // Requirements //------------------------------------------------------------------------------ -import rule from '../../src/rules/no-type-alias'; +import rule from '../../src/rules/no-useless-constructor'; import RuleTester from '../RuleTester'; const ruleTester = new RuleTester({ From ecc95828bc7855fe7a83436a8ffef271e0e13292 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 4 Feb 2019 22:22:26 -0800 Subject: [PATCH 66/92] no-var-requires --- .../src/rules/no-var-requires.ts | 19 ++++++++++++++----- .../tests/rules/no-var-requires.test.ts | 6 +++--- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-var-requires.ts b/packages/eslint-plugin/src/rules/no-var-requires.ts index c92954ab8187..d935386b7eb0 100644 --- a/packages/eslint-plugin/src/rules/no-var-requires.ts +++ b/packages/eslint-plugin/src/rules/no-var-requires.ts @@ -3,7 +3,7 @@ * @author Macklin Underdown */ -import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; +import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; @@ -11,17 +11,23 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -const rule: RuleModule = { +type Options = []; +type MessageIds = 'noVarReqs'; + +const rule: RuleModule = { meta: { type: 'problem', docs: { description: 'Disallows the use of require statements except in import statements', extraDescription: [util.tslintRule('no-var-requires')], - category: 'TypeScript', + category: 'Best Practices', url: util.metaDocsUrl('no-var-requires'), recommended: 'error' }, + messages: { + noVarReqs: 'Require statement not part of import statement.' + }, schema: [] }, create(context) { @@ -30,14 +36,16 @@ const rule: RuleModule = { //---------------------------------------------------------------------- return { - CallExpression(node) { + CallExpression(node: TSESTree.CallExpression) { if ( + node.callee.type === AST_NODE_TYPES.Identifier && node.callee.name === 'require' && + node.parent && node.parent.type === AST_NODE_TYPES.VariableDeclarator ) { context.report({ node, - message: 'Require statement not part of import statement.' + messageId: 'noVarReqs' }); } } @@ -45,3 +53,4 @@ const rule: RuleModule = { } }; export default rule; +export { Options, MessageIds }; diff --git a/packages/eslint-plugin/tests/rules/no-var-requires.test.ts b/packages/eslint-plugin/tests/rules/no-var-requires.test.ts index 5a1bc700ea92..96227fcb3095 100644 --- a/packages/eslint-plugin/tests/rules/no-var-requires.test.ts +++ b/packages/eslint-plugin/tests/rules/no-var-requires.test.ts @@ -25,7 +25,7 @@ ruleTester.run('no-var-requires', rule, { code: "var foo = require('foo')", errors: [ { - message: 'Require statement not part of import statement.', + messageId: 'noVarReqs', line: 1, column: 11 } @@ -35,7 +35,7 @@ ruleTester.run('no-var-requires', rule, { code: "const foo = require('foo')", errors: [ { - message: 'Require statement not part of import statement.', + messageId: 'noVarReqs', line: 1, column: 13 } @@ -45,7 +45,7 @@ ruleTester.run('no-var-requires', rule, { code: "let foo = require('foo')", errors: [ { - message: 'Require statement not part of import statement.', + messageId: 'noVarReqs', line: 1, column: 11 } From 55542a2160e55d6f9a51656090510c9d1192f3c2 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 4 Feb 2019 22:27:35 -0800 Subject: [PATCH 67/92] prefer-interface --- .../src/rules/prefer-interface.ts | 36 +++++++++++-------- packages/eslint-plugin/typings/ts-eslint.d.ts | 2 +- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/packages/eslint-plugin/src/rules/prefer-interface.ts b/packages/eslint-plugin/src/rules/prefer-interface.ts index ee4ac7cf3ff0..c48e8648c500 100644 --- a/packages/eslint-plugin/src/rules/prefer-interface.ts +++ b/packages/eslint-plugin/src/rules/prefer-interface.ts @@ -3,22 +3,25 @@ * @author Armano */ -import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; +import { TSESTree } from '@typescript-eslint/typescript-estree'; +import RuleModule, { RuleFix } from 'ts-eslint'; import * as util from '../util'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -const rule: RuleModule = { +type Options = []; +type MessageIds = 'interfaceOverType'; + +const rule: RuleModule = { meta: { type: 'suggestion', docs: { description: 'Prefer an interface declaration over a type literal (type T = { ... })', extraDescription: [util.tslintRule('interface-over-type-literal')], - category: 'TypeScript', + category: 'Stylistic Issues', url: util.metaDocsUrl('prefer-interface'), recommended: 'error' }, @@ -36,26 +39,31 @@ const rule: RuleModule = { //---------------------------------------------------------------------- return { // VariableDeclaration with kind type has only one VariableDeclarator - "TSTypeAliasDeclaration[typeAnnotation.type='TSTypeLiteral']"(node) { + "TSTypeAliasDeclaration[typeAnnotation.type='TSTypeLiteral']"( + node: TSESTree.TSTypeAliasDeclaration + ) { context.report({ node: node.id, messageId: 'interfaceOverType', fix(fixer) { const typeNode = node.typeParameters || node.id; + const fixes: RuleFix[] = []; - const fixes = [ - fixer.replaceText(sourceCode.getFirstToken(node), 'interface'), - fixer.replaceTextRange( - [typeNode.range[1], node.typeAnnotation.range[0]], - ' ' - ) - ]; + const firstToken = sourceCode.getFirstToken(node); + if (firstToken) { + fixes.push(fixer.replaceText(firstToken, 'interface')); + fixes.push( + fixer.replaceTextRange( + [typeNode.range[1], node.typeAnnotation.range[0]], + ' ' + ) + ); + } const afterToken = sourceCode.getTokenAfter(node.typeAnnotation); - if ( afterToken && - afterToken.type === AST_NODE_TYPES.Punctuator && + afterToken.type === 'Punctuator' && afterToken.value === ';' ) { fixes.push(fixer.remove(afterToken)); diff --git a/packages/eslint-plugin/typings/ts-eslint.d.ts b/packages/eslint-plugin/typings/ts-eslint.d.ts index c7ce1e4fac9a..37cb9c1bbdea 100644 --- a/packages/eslint-plugin/typings/ts-eslint.d.ts +++ b/packages/eslint-plugin/typings/ts-eslint.d.ts @@ -509,6 +509,6 @@ declare module 'ts-eslint' { type Definition = DefinitionType & { name: TSESTree.Identifier }; } - export { RuleContext, ReportFixFunction, ReportDescriptor, Scope }; + export { RuleContext, RuleFix, ReportFixFunction, ReportDescriptor, Scope }; export default RuleModule; } From 4e0136d2627a84142465bd5492b1886a989f76cc Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 4 Feb 2019 22:31:59 -0800 Subject: [PATCH 68/92] prefer-namespace-keyword --- .../src/rules/prefer-namespace-keyword.ts | 18 ++++++++++++------ .../rules/prefer-namespace-keyword.test.ts | 12 ++++-------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts b/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts index 05fba5a657f9..cbed97e936a1 100644 --- a/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts +++ b/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts @@ -4,7 +4,7 @@ * @author Armano */ -import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; +import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; @@ -12,18 +12,25 @@ import * as util from '../util'; // Rule Definition //------------------------------------------------------------------------------ -const rule: RuleModule = { +type Options = []; +type MessageIds = 'useNamespace'; + +const rule: RuleModule = { meta: { type: 'suggestion', docs: { description: 'Require the use of the `namespace` keyword instead of the `module` keyword to declare custom TypeScript modules.', extraDescription: [util.tslintRule('no-internal-module')], - category: 'TypeScript', + category: 'Best Practices', url: util.metaDocsUrl('prefer-namespace-keyword'), recommended: 'error' }, fixable: 'code', + messages: { + useNamespace: + "Use 'namespace' instead of 'module' to declare custom TypeScript modules." + }, schema: [] }, @@ -34,7 +41,7 @@ const rule: RuleModule = { // Public //---------------------------------------------------------------------- return { - TSModuleDeclaration(node) { + TSModuleDeclaration(node: TSESTree.TSModuleDeclaration) { // Do nothing if the name is a string. if (!node.id || node.id.type === AST_NODE_TYPES.Literal) { return; @@ -49,8 +56,7 @@ const rule: RuleModule = { ) { context.report({ node, - message: - "Use 'namespace' instead of 'module' to declare custom TypeScript modules.", + messageId: 'useNamespace', fix(fixer) { return fixer.replaceText(moduleType, 'namespace'); } diff --git a/packages/eslint-plugin/tests/rules/prefer-namespace-keyword.test.ts b/packages/eslint-plugin/tests/rules/prefer-namespace-keyword.test.ts index 4a4e5253a7b0..c8025a248552 100644 --- a/packages/eslint-plugin/tests/rules/prefer-namespace-keyword.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-namespace-keyword.test.ts @@ -33,8 +33,7 @@ ruleTester.run('prefer-namespace-keyword', rule, { output: 'namespace foo { }', errors: [ { - message: - "Use 'namespace' instead of 'module' to declare custom TypeScript modules.", + messageId: 'useNamespace', line: 1, column: 1 } @@ -45,8 +44,7 @@ ruleTester.run('prefer-namespace-keyword', rule, { output: 'declare namespace foo { }', errors: [ { - message: - "Use 'namespace' instead of 'module' to declare custom TypeScript modules.", + messageId: 'useNamespace', line: 1, column: 1 } @@ -65,14 +63,12 @@ declare namespace foo { `, errors: [ { - message: - "Use 'namespace' instead of 'module' to declare custom TypeScript modules.", + messageId: 'useNamespace', line: 2, column: 1 }, { - message: - "Use 'namespace' instead of 'module' to declare custom TypeScript modules.", + messageId: 'useNamespace', line: 3, column: 5 } From 50dda72ed25d37c70a6682168ba66283a0eca9c1 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 4 Feb 2019 22:34:26 -0800 Subject: [PATCH 69/92] restrict-plus-operands --- .../src/rules/restrict-plus-operands.ts | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts index a5346136421a..24d037b0819b 100644 --- a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts +++ b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts @@ -7,19 +7,24 @@ import RuleModule from 'ts-eslint'; import ts from 'typescript'; import * as util from '../util'; +import { TSESTree } from '@typescript-eslint/typescript-estree'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -const rule: RuleModule = { +type Options = []; +type MessageIds = 'notNumbers' | 'notStrings'; + +const rule: RuleModule = { meta: { type: 'problem', docs: { description: 'When adding two variables, operands must both be of type number or of type string.', extraDescription: [util.tslintRule('restrict-plus-operands')], - category: 'TypeScript', + category: 'Best Practices', + recommended: false, url: util.metaDocsUrl('restrict-plus-operands') }, messages: { @@ -36,14 +41,14 @@ const rule: RuleModule = { const typeChecker = service.program.getTypeChecker(); + type BaseLiteral = 'string' | 'number' | 'invalid'; + /** * Helper function to get base type of node * @param type type to be evaluated * @returns string, number or invalid */ - function getBaseTypeOfLiteralType( - type: ts.Type - ): 'string' | 'number' | 'invalid' { + function getBaseTypeOfLiteralType(type: ts.Type): BaseLiteral { if (type.isNumberLiteral()) { return 'number'; } @@ -66,10 +71,9 @@ const rule: RuleModule = { /** * Helper function to get base type of node - * @param {ASTNode} node the node to be evaluated. - * @returns {*} string, number or invalid + * @param node the node to be evaluated. */ - function getNodeType(node) { + function getNodeType(node: TSESTree.Node): BaseLiteral { const tsNode = service.esTreeNodeToTSNodeMap.get(node); const type = typeChecker.getTypeAtLocation(tsNode); @@ -80,7 +84,7 @@ const rule: RuleModule = { // Public //---------------------------------------------------------------------- return { - "BinaryExpression[operator='+']"(node) { + "BinaryExpression[operator='+']"(node: TSESTree.BinaryExpression) { const leftType = getNodeType(node.left); const rightType = getNodeType(node.right); From f6527ddf060e37ee5aebbbaf0a7cc43d4563f1c6 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 4 Feb 2019 23:02:09 -0800 Subject: [PATCH 70/92] type-annotation-spacing --- .../src/rules/type-annotation-spacing.ts | 66 +- packages/eslint-plugin/tests/RuleTester.ts | 2 +- .../rules/type-annotation-spacing.test.ts | 1194 ++++++++++++----- 3 files changed, 871 insertions(+), 391 deletions(-) diff --git a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts index 385a0aa61698..92f39a86baa1 100644 --- a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts +++ b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts @@ -6,11 +6,34 @@ import RuleModule from 'ts-eslint'; import * as util from '../util'; +import { TSESTree } from '@typescript-eslint/typescript-estree'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ +type Options = [ + { + before?: boolean; + after?: boolean; + overrides?: { + colon?: { + before?: boolean; + after?: boolean; + }; + arrow?: { + before?: boolean; + after?: boolean; + }; + }; + }? +]; +type MessageIds = + | 'expectedSpaceAfter' + | 'expectedSpaceBefore' + | 'unexpectedSpaceAfter' + | 'unexpectedSpaceBefore'; + const definition = { type: 'object', properties: { @@ -20,23 +43,29 @@ const definition = { additionalProperties: false }; -const defaultOptions = [ +const defaultOptions: Options = [ // technically there is a default, but the overrides mean // that if we apply them here, it will break the no override case. {} ]; -const rule: RuleModule = { +const rule: RuleModule = { meta: { type: 'layout', docs: { description: 'Require consistent spacing around type annotations', extraDescription: [util.tslintRule('typedef-whitespace')], - category: 'TypeScript', + category: 'Stylistic Issues', url: util.metaDocsUrl('type-annotation-spacing'), recommended: 'error' }, fixable: 'whitespace', + messages: { + expectedSpaceAfter: "Expected a space after the '{{type}}'.", + expectedSpaceBefore: "Expected a space before the '{{type}}'.", + unexpectedSpaceAfter: "Unexpected a space after the '{{type}}'.", + unexpectedSpaceBefore: "Unexpected a space before the '{{type}}'." + }, schema: [ { type: 'object', @@ -51,7 +80,8 @@ const rule: RuleModule = { }, additionalProperties: false } - } + }, + additionalProperties: false } ] }, @@ -61,7 +91,7 @@ const rule: RuleModule = { const sourceCode = context.getSourceCode(); const options = util.applyDefault(defaultOptions, context.options)[0]; - const overrides = options.overrides || {}; + const overrides = options!.overrides || { colon: {}, arrow: {} }; const colonOptions = Object.assign( {}, @@ -83,13 +113,14 @@ const rule: RuleModule = { /** * Checks if there's proper spacing around type annotations (no space * before colon, one space after). - * @param {ASTNode} typeAnnotation The TSTypeAnnotation node. */ - function checkTypeAnnotationSpacing(typeAnnotation): void { + function checkTypeAnnotationSpacing( + typeAnnotation: TSESTree.TypeNode + ): void { const nextToken = typeAnnotation; - const punctuatorTokenEnd = sourceCode.getTokenBefore(nextToken); + const punctuatorTokenEnd = sourceCode.getTokenBefore(nextToken)!; let punctuatorTokenStart = punctuatorTokenEnd; - let previousToken = sourceCode.getTokenBefore(punctuatorTokenEnd); + let previousToken = sourceCode.getTokenBefore(punctuatorTokenEnd)!; let type = punctuatorTokenEnd.value; if (punctuators.indexOf(type) === -1) { @@ -103,13 +134,13 @@ const rule: RuleModule = { // shift the start to the ? type = '?:'; punctuatorTokenStart = previousToken; - previousToken = sourceCode.getTokenBefore(previousToken); + previousToken = sourceCode.getTokenBefore(previousToken)!; // handle the +/- modifiers for optional modification operators if (previousToken.value === '+' || previousToken.value === '-') { type = `${previousToken.value}?:`; punctuatorTokenStart = previousToken; - previousToken = sourceCode.getTokenBefore(previousToken); + previousToken = sourceCode.getTokenBefore(previousToken)!; } } @@ -120,7 +151,7 @@ const rule: RuleModule = { if (after && nextDelta === 0) { context.report({ node: punctuatorTokenEnd, - message: "Expected a space after the '{{type}}'.", + messageId: 'expectedSpaceAfter', data: { type }, @@ -131,7 +162,7 @@ const rule: RuleModule = { } else if (!after && nextDelta > 0) { context.report({ node: punctuatorTokenEnd, - message: "Unexpected space after the '{{type}}'.", + messageId: 'unexpectedSpaceAfter', data: { type }, @@ -147,7 +178,7 @@ const rule: RuleModule = { if (before && previousDelta === 0) { context.report({ node: punctuatorTokenStart, - message: "Expected a space before the '{{type}}'.", + messageId: 'expectedSpaceBefore', data: { type }, @@ -158,7 +189,7 @@ const rule: RuleModule = { } else if (!before && previousDelta > 0) { context.report({ node: punctuatorTokenStart, - message: "Unexpected space before the '{{type}}'.", + messageId: 'unexpectedSpaceBefore', data: { type }, @@ -176,15 +207,16 @@ const rule: RuleModule = { // Public //---------------------------------------------------------------------- return { - TSMappedType(node) { + TSMappedType(node: TSESTree.TSMappedType) { if (node.typeAnnotation) { checkTypeAnnotationSpacing(node.typeAnnotation); } }, - TSTypeAnnotation(node) { + TSTypeAnnotation(node: TSESTree.TSTypeAnnotation) { checkTypeAnnotationSpacing(node.typeAnnotation); } }; } }; export default rule; +export { Options, MessageIds }; diff --git a/packages/eslint-plugin/tests/RuleTester.ts b/packages/eslint-plugin/tests/RuleTester.ts index 1e52496afad7..f6bdcaef40ef 100644 --- a/packages/eslint-plugin/tests/RuleTester.ts +++ b/packages/eslint-plugin/tests/RuleTester.ts @@ -46,4 +46,4 @@ const RuleTesterRetyped = (RuleTester as any) as { new (config?: any): RuleTesterTyped; }; export default RuleTesterRetyped; -export { RunTests, TestCaseError }; +export { RunTests, TestCaseError, InvalidTestCase, ValidTestCase }; diff --git a/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts index 26e7b832cf66..026af50f6ca3 100644 --- a/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts @@ -7,8 +7,11 @@ // Requirements //------------------------------------------------------------------------------ -import rule from '../../src/rules/type-annotation-spacing'; -import RuleTester from '../RuleTester'; +import rule, { + Options, + MessageIds +} from '../../src/rules/type-annotation-spacing'; +import RuleTester, { InvalidTestCase, ValidTestCase } from '../RuleTester'; //------------------------------------------------------------------------------ // Tests @@ -1043,7 +1046,8 @@ type Bar = Record output: 'let foo: string;', errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 1, column: 9 } @@ -1054,7 +1058,8 @@ type Bar = Record output: 'function foo(): string {}', errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 1, column: 16 } @@ -1065,7 +1070,8 @@ type Bar = Record output: 'function foo(a: string) {}', errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 1, column: 16 } @@ -1084,7 +1090,8 @@ class Foo { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 10 } @@ -1103,7 +1110,8 @@ class Foo { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 25 } @@ -1122,7 +1130,8 @@ class Foo { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 13 } @@ -1141,12 +1150,14 @@ class Foo { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 16 }, { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 26 } @@ -1165,7 +1176,8 @@ interface Foo { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 10 } @@ -1184,7 +1196,8 @@ interface Foo { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 13 } @@ -1203,12 +1216,14 @@ interface Foo { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 16 }, { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 26 } @@ -1227,7 +1242,8 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 10 } @@ -1246,7 +1262,8 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 13 } @@ -1265,12 +1282,14 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 16 }, { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 26 } @@ -1281,7 +1300,8 @@ type Foo = { output: 'type Foo = (name: string) => string;', errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 1, column: 18 } @@ -1292,12 +1312,14 @@ type Foo = { output: 'type Foo = (name: string) => string;', errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 1, column: 18 }, { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 1, column: 27 } @@ -1316,7 +1338,8 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 18 } @@ -1335,12 +1358,14 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 18 }, { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 3, column: 27 } @@ -1352,7 +1377,8 @@ type Foo = { output: 'let foo: string;', errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 1, column: 9 } @@ -1364,7 +1390,8 @@ type Foo = { output: 'function foo(): string {}', errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 1, column: 16 } @@ -1376,7 +1403,8 @@ type Foo = { output: 'function foo(a: string) {}', errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 1, column: 16 } @@ -1396,7 +1424,8 @@ class Foo { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 10 } @@ -1416,7 +1445,8 @@ class Foo { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 25 } @@ -1436,7 +1466,8 @@ class Foo { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 13 } @@ -1456,12 +1487,14 @@ class Foo { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 16 }, { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 26 } @@ -1481,7 +1514,8 @@ interface Foo { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 10 } @@ -1501,7 +1535,8 @@ interface Foo { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 13 } @@ -1521,12 +1556,14 @@ interface Foo { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 16 }, { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 26 } @@ -1546,7 +1583,8 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 10 } @@ -1566,7 +1604,8 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 13 } @@ -1586,12 +1625,14 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 16 }, { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 26 } @@ -1603,7 +1644,8 @@ type Foo = { output: 'type Foo = (name: string) => string;', errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 1, column: 18 } @@ -1615,12 +1657,14 @@ type Foo = { output: 'type Foo = (name: string) => string;', errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 1, column: 18 }, { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 1, column: 27 } @@ -1640,7 +1684,8 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 18 } @@ -1660,12 +1705,14 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 18 }, { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 3, column: 27 } @@ -1677,7 +1724,8 @@ type Foo = { output: 'let foo: string;', errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 1, column: 9 } @@ -1689,7 +1737,8 @@ type Foo = { output: 'function foo(): string {}', errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 1, column: 16 } @@ -1701,7 +1750,8 @@ type Foo = { output: 'function foo(a: string) {}', errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 1, column: 16 } @@ -1721,7 +1771,8 @@ class Foo { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 10 } @@ -1741,7 +1792,8 @@ class Foo { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 25 } @@ -1761,7 +1813,8 @@ class Foo { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 13 } @@ -1781,12 +1834,14 @@ class Foo { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 16 }, { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 26 } @@ -1806,7 +1861,8 @@ interface Foo { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 10 } @@ -1826,7 +1882,8 @@ interface Foo { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 13 } @@ -1846,12 +1903,14 @@ interface Foo { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 16 }, { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 26 } @@ -1871,7 +1930,8 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 10 } @@ -1891,7 +1951,8 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 13 } @@ -1911,12 +1972,14 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 16 }, { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 26 } @@ -1928,12 +1991,14 @@ type Foo = { output: 'type Foo = (name: string)=> string;', errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 1, column: 18 }, { - message: "Unexpected space before the '=>'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '=>' }, line: 1, column: 28 } @@ -1945,7 +2010,8 @@ type Foo = { output: 'type Foo = (name: string)=> string;', errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 1, column: 18 } @@ -1965,12 +2031,14 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 18 }, { - message: "Unexpected space before the '=>'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '=>' }, line: 3, column: 28 } @@ -1990,7 +2058,8 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 18 } @@ -2002,12 +2071,14 @@ type Foo = { output: 'let foo : string;', errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 1, column: 8 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 1, column: 8 } @@ -2019,12 +2090,14 @@ type Foo = { output: 'function foo() : string {}', errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 1, column: 15 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 1, column: 15 } @@ -2036,12 +2109,14 @@ type Foo = { output: 'function foo(a : string) {}', errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 1, column: 15 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 1, column: 15 } @@ -2061,12 +2136,14 @@ class Foo { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 9 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 9 } @@ -2086,12 +2163,14 @@ class Foo { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 24 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 24 } @@ -2111,12 +2190,14 @@ class Foo { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 12 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 12 } @@ -2136,22 +2217,26 @@ class Foo { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 15 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 15 }, { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 23 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 23 } @@ -2171,12 +2256,14 @@ interface Foo { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 9 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 9 } @@ -2196,12 +2283,14 @@ interface Foo { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 12 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 12 } @@ -2221,22 +2310,26 @@ interface Foo { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 15 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 15 }, { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 23 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 23 } @@ -2256,12 +2349,14 @@ type Foo = { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 9 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 9 } @@ -2281,12 +2376,14 @@ type Foo = { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 12 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 12 } @@ -2306,22 +2403,26 @@ type Foo = { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 15 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 15 }, { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 23 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 23 } @@ -2333,12 +2434,14 @@ type Foo = { output: 'type Foo = (name : string) => string;', errors: [ { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 1, column: 17 }, { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 1, column: 26 } @@ -2350,7 +2453,8 @@ type Foo = { output: 'type Foo = (name : string) => string;', errors: [ { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 1, column: 27 } @@ -2370,17 +2474,20 @@ type Foo = { `, errors: [ { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 10 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 17 }, { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 3, column: 26 } @@ -2400,7 +2507,8 @@ type Foo = { `, errors: [ { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 3, column: 28 } @@ -2412,12 +2520,14 @@ type Foo = { output: 'let foo : string;', errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 1, column: 8 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 1, column: 8 } @@ -2429,12 +2539,14 @@ type Foo = { output: 'function foo() : string {}', errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 1, column: 15 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 1, column: 15 } @@ -2446,12 +2558,14 @@ type Foo = { output: 'function foo(a : string) {}', errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 1, column: 15 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 1, column: 15 } @@ -2471,12 +2585,14 @@ class Foo { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 9 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 9 } @@ -2496,12 +2612,14 @@ class Foo { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 24 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 24 } @@ -2521,12 +2639,14 @@ class Foo { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 12 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 12 } @@ -2546,22 +2666,26 @@ class Foo { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 15 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 15 }, { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 23 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 23 } @@ -2581,12 +2705,14 @@ interface Foo { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 9 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 9 } @@ -2606,12 +2732,14 @@ interface Foo { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 12 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 12 } @@ -2631,22 +2759,26 @@ interface Foo { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 15 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 15 }, { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 23 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 23 } @@ -2666,12 +2798,14 @@ type Foo = { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 9 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 9 } @@ -2691,12 +2825,14 @@ type Foo = { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 12 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 12 } @@ -2716,22 +2852,26 @@ type Foo = { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 15 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 15 }, { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 23 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 23 } @@ -2743,12 +2883,14 @@ type Foo = { output: 'type Foo = (name : string) => string;', errors: [ { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 1, column: 17 }, { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 1, column: 26 } @@ -2760,7 +2902,8 @@ type Foo = { output: 'type Foo = (name : string) => string;', errors: [ { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 1, column: 27 } @@ -2780,17 +2923,20 @@ type Foo = { `, errors: [ { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 10 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 17 }, { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 3, column: 26 } @@ -2810,7 +2956,8 @@ type Foo = { `, errors: [ { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 3, column: 28 } @@ -2828,12 +2975,14 @@ type Foo = { output: 'let foo : string;', errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 1, column: 8 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 1, column: 8 } @@ -2851,12 +3000,14 @@ type Foo = { output: 'function foo() : string {}', errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 1, column: 15 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 1, column: 15 } @@ -2874,12 +3025,14 @@ type Foo = { output: 'function foo(a : string) {}', errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 1, column: 15 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 1, column: 15 } @@ -2905,12 +3058,14 @@ class Foo { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 9 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 9 } @@ -2936,12 +3091,14 @@ class Foo { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 24 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 24 } @@ -2967,12 +3124,14 @@ class Foo { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 12 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 12 } @@ -2998,22 +3157,26 @@ class Foo { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 15 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 15 }, { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 23 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 23 } @@ -3039,12 +3202,14 @@ interface Foo { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 9 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 9 } @@ -3070,12 +3235,14 @@ interface Foo { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 12 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 12 } @@ -3101,22 +3268,26 @@ interface Foo { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 15 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 15 }, { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 23 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 23 } @@ -3142,12 +3313,14 @@ type Foo = { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 9 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 9 } @@ -3173,12 +3346,14 @@ type Foo = { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 12 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 12 } @@ -3204,22 +3379,26 @@ type Foo = { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 15 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 15 }, { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 23 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 23 } @@ -3237,12 +3416,14 @@ type Foo = { output: 'type Foo = (name : string)=>string;', errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 1, column: 17 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 1, column: 17 } @@ -3268,12 +3449,14 @@ type Foo = { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 18 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 18 } @@ -3300,22 +3483,26 @@ type Foo = { output: 'type Foo = (name : string) => string;', errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 1, column: 17 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 1, column: 17 }, { - message: "Expected a space after the '=>'.", + messageId: 'expectedSpaceAfter', + data: { type: '=>' }, line: 1, column: 25 }, { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 1, column: 25 } @@ -3350,22 +3537,26 @@ type Foo = { `, errors: [ { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 18 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 18 }, { - message: "Expected a space after the '=>'.", + messageId: 'expectedSpaceAfter', + data: { type: '=>' }, line: 3, column: 26 }, { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 3, column: 26 } @@ -3390,47 +3581,74 @@ type Foo = { `, errors: [ { - message: `Expected a space before the ':'.`, + messageId: 'expectedSpaceBefore', + data: { + type: '.' + }, line: 3, column: 30 }, { - message: `Expected a space before the ':'.`, + messageId: 'expectedSpaceBefore', + data: { + type: '.' + }, line: 3, column: 45 }, { - message: `Expected a space before the ':'.`, + messageId: 'expectedSpaceBefore', + data: { + type: '.' + }, line: 3, column: 52 }, { - message: `Expected a space before the ':'.`, + messageId: 'expectedSpaceBefore', + data: { + type: '.' + }, line: 4, column: 47 }, { - message: `Expected a space before the ':'.`, + messageId: 'expectedSpaceBefore', + data: { + type: '.' + }, line: 4, column: 62 }, { - message: `Expected a space before the ':'.`, + messageId: 'expectedSpaceBefore', + data: { + type: '.' + }, line: 4, column: 69 }, { - message: `Expected a space before the ':'.`, + messageId: 'expectedSpaceBefore', + data: { + type: '.' + }, line: 5, column: 45 }, { - message: `Expected a space before the ':'.`, + messageId: 'expectedSpaceBefore', + data: { + type: '.' + }, line: 5, column: 60 }, { - message: `Expected a space before the ':'.`, + messageId: 'expectedSpaceBefore', + data: { + type: '.' + }, line: 5, column: 67 } @@ -4227,7 +4445,8 @@ type Bar = Record output: 'function foo(a?: string) {}', errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 1, column: 16 } @@ -4246,7 +4465,8 @@ class Foo { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 10 } @@ -4265,7 +4485,8 @@ class Foo { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 25 } @@ -4284,12 +4505,14 @@ class Foo { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 16 }, { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 27 } @@ -4308,7 +4531,8 @@ interface Foo { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 10 } @@ -4327,12 +4551,14 @@ interface Foo { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 16 }, { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 27 } @@ -4351,7 +4577,8 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 10 } @@ -4370,12 +4597,14 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 16 }, { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 27 } @@ -4386,7 +4615,8 @@ type Foo = { output: 'type Foo = (name?: string) => string;', errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 1, column: 18 } @@ -4397,12 +4627,14 @@ type Foo = { output: 'type Foo = (name?: string) => string;', errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 1, column: 18 }, { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 1, column: 28 } @@ -4421,7 +4653,8 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 18 } @@ -4440,12 +4673,14 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 18 }, { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 3, column: 28 } @@ -4457,7 +4692,8 @@ type Foo = { output: 'function foo(a?: string) {}', errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 1, column: 16 } @@ -4477,7 +4713,8 @@ class Foo { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 10 } @@ -4497,7 +4734,8 @@ class Foo { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 25 } @@ -4517,12 +4755,14 @@ class Foo { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 16 }, { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 27 } @@ -4542,7 +4782,8 @@ interface Foo { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 10 } @@ -4562,12 +4803,14 @@ interface Foo { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 16 }, { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 27 } @@ -4587,7 +4830,8 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 10 } @@ -4607,12 +4851,14 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 16 }, { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 27 } @@ -4624,7 +4870,8 @@ type Foo = { output: 'type Foo = (name?: string) => string;', errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 1, column: 18 } @@ -4636,12 +4883,14 @@ type Foo = { output: 'type Foo = (name?: string) => string;', errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 1, column: 18 }, { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 1, column: 28 } @@ -4661,7 +4910,8 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 18 } @@ -4681,12 +4931,14 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 18 }, { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 3, column: 28 } @@ -4698,7 +4950,8 @@ type Foo = { output: 'function foo(a?: string) {}', errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 1, column: 16 } @@ -4718,7 +4971,8 @@ class Foo { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 10 } @@ -4738,7 +4992,8 @@ class Foo { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 25 } @@ -4758,12 +5013,14 @@ class Foo { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 16 }, { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 27 } @@ -4783,7 +5040,8 @@ interface Foo { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 10 } @@ -4803,12 +5061,14 @@ interface Foo { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 16 }, { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 27 } @@ -4828,7 +5088,8 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 10 } @@ -4848,12 +5109,14 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 16 }, { - message: "Unexpected space before the ':'.", + messageId: 'unexpectedSpaceBefore', + data: { type: ':' }, line: 3, column: 27 } @@ -4865,12 +5128,14 @@ type Foo = { output: 'type Foo = (name?: string)=> string;', errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 1, column: 18 }, { - message: "Unexpected space before the '=>'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '=>' }, line: 1, column: 29 } @@ -4882,7 +5147,8 @@ type Foo = { output: 'type Foo = (name?: string)=> string;', errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 1, column: 18 } @@ -4902,12 +5168,14 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 18 }, { - message: "Unexpected space before the '=>'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '=>' }, line: 3, column: 29 } @@ -4927,7 +5195,8 @@ type Foo = { `, errors: [ { - message: "Unexpected space before the '?:'.", + messageId: 'unexpectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 18 } @@ -4939,12 +5208,14 @@ type Foo = { output: 'function foo(a ?: string) {}', errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 1, column: 15 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 1, column: 16 } @@ -4964,12 +5235,14 @@ class Foo { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 9 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 3, column: 10 } @@ -4989,12 +5262,14 @@ class Foo { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 24 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 3, column: 25 } @@ -5014,22 +5289,26 @@ class Foo { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 15 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 3, column: 16 }, { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 24 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 24 } @@ -5049,12 +5328,14 @@ interface Foo { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 9 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 3, column: 10 } @@ -5074,22 +5355,26 @@ interface Foo { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 15 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 3, column: 16 }, { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 24 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 24 } @@ -5109,12 +5394,14 @@ type Foo = { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 9 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 3, column: 10 } @@ -5134,22 +5421,26 @@ type Foo = { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 15 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 3, column: 16 }, { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 24 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 24 } @@ -5161,12 +5452,14 @@ type Foo = { output: 'type Foo = (name ?: string) => string;', errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 1, column: 17 }, { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 1, column: 27 } @@ -5178,7 +5471,8 @@ type Foo = { output: 'type Foo = (name ?: string) => string;', errors: [ { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 1, column: 28 } @@ -5198,17 +5492,20 @@ type Foo = { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 10 }, { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 18 }, { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 3, column: 28 } @@ -5228,7 +5525,8 @@ type Foo = { `, errors: [ { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 3, column: 30 } @@ -5240,12 +5538,14 @@ type Foo = { output: 'function foo(a ?: string) {}', errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 1, column: 15 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 1, column: 16 } @@ -5265,12 +5565,14 @@ class Foo { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 9 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 3, column: 10 } @@ -5290,12 +5592,14 @@ class Foo { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 24 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 3, column: 25 } @@ -5315,22 +5619,26 @@ class Foo { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 15 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 3, column: 16 }, { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 24 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 24 } @@ -5350,12 +5658,14 @@ interface Foo { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 9 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 3, column: 10 } @@ -5375,22 +5685,26 @@ interface Foo { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 15 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 3, column: 16 }, { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 24 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 24 } @@ -5410,12 +5724,14 @@ type Foo = { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 9 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 3, column: 10 } @@ -5435,22 +5751,26 @@ type Foo = { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 15 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 3, column: 16 }, { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 24 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 24 } @@ -5462,12 +5782,14 @@ type Foo = { output: 'type Foo = (name ?: string) => string;', errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 1, column: 17 }, { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 1, column: 27 } @@ -5479,7 +5801,8 @@ type Foo = { output: 'type Foo = (name : string) => string;', errors: [ { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 1, column: 27 } @@ -5499,17 +5822,20 @@ type Foo = { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 10 }, { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 18 }, { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 3, column: 28 } @@ -5529,7 +5855,8 @@ type Foo = { `, errors: [ { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 3, column: 30 } @@ -5547,12 +5874,14 @@ type Foo = { output: 'function foo(a ?: string) {}', errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 1, column: 15 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 1, column: 16 } @@ -5578,12 +5907,14 @@ class Foo { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 9 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 3, column: 10 } @@ -5609,12 +5940,14 @@ class Foo { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 24 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 3, column: 25 } @@ -5640,22 +5973,26 @@ class Foo { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 15 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 3, column: 16 }, { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 24 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 24 } @@ -5681,12 +6018,14 @@ interface Foo { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 9 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 3, column: 10 } @@ -5712,22 +6051,26 @@ interface Foo { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 15 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 3, column: 16 }, { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 24 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 24 } @@ -5753,12 +6096,14 @@ type Foo = { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 9 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 3, column: 10 } @@ -5784,22 +6129,26 @@ type Foo = { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 15 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 3, column: 16 }, { - message: "Expected a space after the ':'.", + messageId: 'expectedSpaceAfter', + data: { type: ':' }, line: 3, column: 24 }, { - message: "Expected a space before the ':'.", + messageId: 'expectedSpaceBefore', + data: { type: ':' }, line: 3, column: 24 } @@ -5817,12 +6166,14 @@ type Foo = { output: 'type Foo = (name ?: string)=>string;', errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 1, column: 17 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 1, column: 18 } @@ -5848,12 +6199,14 @@ type Foo = { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 19 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 3, column: 20 } @@ -5880,22 +6233,26 @@ type Foo = { output: 'type Foo = (name ?: string) => string;', errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 1, column: 17 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 1, column: 18 }, { - message: "Expected a space after the '=>'.", + messageId: 'expectedSpaceAfter', + data: { type: '=>' }, line: 1, column: 26 }, { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 1, column: 26 } @@ -5930,22 +6287,26 @@ type Foo = { `, errors: [ { - message: "Expected a space before the '?:'.", + messageId: 'expectedSpaceBefore', + data: { type: '?:' }, line: 3, column: 19 }, { - message: "Expected a space after the '?:'.", + messageId: 'expectedSpaceAfter', + data: { type: '?:' }, line: 3, column: 20 }, { - message: "Expected a space after the '=>'.", + messageId: 'expectedSpaceAfter', + data: { type: '=>' }, line: 3, column: 28 }, { - message: "Expected a space before the '=>'.", + messageId: 'expectedSpaceBefore', + data: { type: '=>' }, line: 3, column: 28 } @@ -5961,7 +6322,7 @@ type Foo = { const operators = ['+?:', '-?:']; ruleTester.run('type-annotation-spacing', rule, { - valid: operators.reduce( + valid: operators.reduce[]>( (validCases, operator) => validCases.concat([ { @@ -6003,7 +6364,7 @@ ruleTester.run('type-annotation-spacing', rule, { ]), [] ), - invalid: operators.reduce( + invalid: operators.reduce[]>( (invalidCases, operator) => invalidCases.concat([ // space before + after cases @@ -6013,7 +6374,10 @@ ruleTester.run('type-annotation-spacing', rule, { output: `type Foo = { [P in keyof T]${operator} T[P] }`, errors: [ { - message: `Unexpected space before the '${operator}'.`, + messageId: 'unexpectedSpaceBefore', + data: { + type: operator + }, line: 1, column: 32 } @@ -6025,7 +6389,10 @@ ruleTester.run('type-annotation-spacing', rule, { output: `type Foo = { [P in keyof T]${operator} T[P] }`, errors: [ { - message: `Unexpected space before the '${operator}'.`, + messageId: 'unexpectedSpaceBefore', + data: { + type: operator + }, line: 1, column: 32 } @@ -6037,7 +6404,10 @@ ruleTester.run('type-annotation-spacing', rule, { output: `type Foo = { [P in keyof T]${operator} T[P] }`, errors: [ { - message: `Unexpected space before the '${operator}'.`, + messageId: 'unexpectedSpaceBefore', + data: { + type: operator + }, line: 1, column: 32 } @@ -6049,12 +6419,18 @@ ruleTester.run('type-annotation-spacing', rule, { output: `type Foo = { [P in keyof T]${operator}T[P] }`, errors: [ { - message: `Unexpected space before the '${operator}'.`, + messageId: 'unexpectedSpaceBefore', + data: { + type: operator + }, line: 1, column: 32 }, { - message: `Unexpected space after the '${operator}'.`, + messageId: 'unexpectedSpaceAfter', + data: { + type: operator + }, line: 1, column: 34 } @@ -6066,12 +6442,18 @@ ruleTester.run('type-annotation-spacing', rule, { output: `type Foo = { [P in keyof T]${operator}T[P] }`, errors: [ { - message: `Unexpected space before the '${operator}'.`, + messageId: 'unexpectedSpaceBefore', + data: { + type: operator + }, line: 1, column: 32 }, { - message: `Unexpected space after the '${operator}'.`, + messageId: 'unexpectedSpaceAfter', + data: { + type: operator + }, line: 1, column: 34 } @@ -6083,7 +6465,10 @@ ruleTester.run('type-annotation-spacing', rule, { output: `type Foo = { [P in keyof T] ${operator}T[P] }`, errors: [ { - message: `Unexpected space after the '${operator}'.`, + messageId: 'unexpectedSpaceAfter', + data: { + type: operator + }, line: 1, column: 34 } @@ -6096,7 +6481,10 @@ ruleTester.run('type-annotation-spacing', rule, { output: `type Foo = { [P in keyof T]${operator} T[P] }`, errors: [ { - message: `Expected a space after the '${operator}'.`, + messageId: 'expectedSpaceAfter', + data: { + type: operator + }, line: 1, column: 33 } @@ -6108,12 +6496,18 @@ ruleTester.run('type-annotation-spacing', rule, { output: `type Foo = { [P in keyof T] ${operator} T[P] }`, errors: [ { - message: `Expected a space before the '${operator}'.`, + messageId: 'expectedSpaceBefore', + data: { + type: operator + }, line: 1, column: 31 }, { - message: `Expected a space after the '${operator}'.`, + messageId: 'expectedSpaceAfter', + data: { + type: operator + }, line: 1, column: 33 } @@ -6125,12 +6519,18 @@ ruleTester.run('type-annotation-spacing', rule, { output: `type Foo = { [P in keyof T] ${operator} T[P] }`, errors: [ { - message: `Expected a space before the '${operator}'.`, + messageId: 'expectedSpaceBefore', + data: { + type: operator + }, line: 1, column: 31 }, { - message: `Expected a space after the '${operator}'.`, + messageId: 'expectedSpaceAfter', + data: { + type: operator + }, line: 1, column: 33 } @@ -6142,7 +6542,10 @@ ruleTester.run('type-annotation-spacing', rule, { output: `type Foo = { [P in keyof T]${operator} T[P] }`, errors: [ { - message: `Expected a space after the '${operator}'.`, + messageId: 'expectedSpaceAfter', + data: { + type: operator + }, line: 1, column: 33 } @@ -6154,7 +6557,10 @@ ruleTester.run('type-annotation-spacing', rule, { output: `type Foo = { [P in keyof T] ${operator}T[P] }`, errors: [ { - message: `Expected a space before the '${operator}'.`, + messageId: 'expectedSpaceBefore', + data: { + type: operator + }, line: 1, column: 31 } @@ -6167,12 +6573,18 @@ ruleTester.run('type-annotation-spacing', rule, { output: `type Foo = { [P in keyof T]${operator} T[P] }`, errors: [ { - message: `Unexpected space before the '${operator}'.`, + messageId: 'unexpectedSpaceBefore', + data: { + type: operator + }, line: 1, column: 32 }, { - message: `Expected a space after the '${operator}'.`, + messageId: 'expectedSpaceAfter', + data: { + type: operator + }, line: 1, column: 34 } @@ -6184,12 +6596,18 @@ ruleTester.run('type-annotation-spacing', rule, { output: `type Foo = { [P in keyof T]${operator} T[P] }`, errors: [ { - message: `Unexpected space before the '${operator}'.`, + messageId: 'unexpectedSpaceBefore', + data: { + type: operator + }, line: 1, column: 32 }, { - message: `Expected a space after the '${operator}'.`, + messageId: 'expectedSpaceAfter', + data: { + type: operator + }, line: 1, column: 34 } @@ -6201,7 +6619,10 @@ ruleTester.run('type-annotation-spacing', rule, { output: `type Foo = { [P in keyof T] ${operator} T[P] }`, errors: [ { - message: `Expected a space after the '${operator}'.`, + messageId: 'expectedSpaceAfter', + data: { + type: operator + }, line: 1, column: 34 } @@ -6213,12 +6634,18 @@ ruleTester.run('type-annotation-spacing', rule, { output: `type Foo = { [P in keyof T]${operator} T[P] }`, errors: [ { - message: `Unexpected space before the '${operator}'.`, + messageId: 'unexpectedSpaceBefore', + data: { + type: operator + }, line: 1, column: 32 }, { - message: `Expected a space after the '${operator}'.`, + messageId: 'expectedSpaceAfter', + data: { + type: operator + }, line: 1, column: 34 } @@ -6230,7 +6657,10 @@ ruleTester.run('type-annotation-spacing', rule, { output: `type Foo = { [P in keyof T] ${operator} T[P] }`, errors: [ { - message: `Expected a space after the '${operator}'.`, + messageId: 'expectedSpaceAfter', + data: { + type: operator + }, line: 1, column: 34 } @@ -6243,7 +6673,10 @@ ruleTester.run('type-annotation-spacing', rule, { output: `type Foo = { [P in keyof T]${operator}T[P] }`, errors: [ { - message: `Unexpected space after the '${operator}'.`, + messageId: 'unexpectedSpaceAfter', + data: { + type: operator + }, line: 1, column: 33 } @@ -6255,7 +6688,10 @@ ruleTester.run('type-annotation-spacing', rule, { output: `type Foo = { [P in keyof T] ${operator} T[P] }`, errors: [ { - message: `Expected a space before the '${operator}'.`, + messageId: 'expectedSpaceBefore', + data: { + type: operator + }, line: 1, column: 31 } @@ -6267,7 +6703,10 @@ ruleTester.run('type-annotation-spacing', rule, { output: `type Foo = { [P in keyof T] ${operator} T[P] }`, errors: [ { - message: `Expected a space before the '${operator}'.`, + messageId: 'expectedSpaceBefore', + data: { + type: operator + }, line: 1, column: 31 } @@ -6279,12 +6718,18 @@ ruleTester.run('type-annotation-spacing', rule, { output: `type Foo = { [P in keyof T] ${operator}T[P] }`, errors: [ { - message: `Expected a space before the '${operator}'.`, + messageId: 'expectedSpaceBefore', + data: { + type: operator + }, line: 1, column: 31 }, { - message: `Unexpected space after the '${operator}'.`, + messageId: 'unexpectedSpaceAfter', + data: { + type: operator + }, line: 1, column: 33 } @@ -6296,7 +6741,10 @@ ruleTester.run('type-annotation-spacing', rule, { output: `type Foo = { [P in keyof T]${operator}T[P] }`, errors: [ { - message: `Unexpected space after the '${operator}'.`, + messageId: 'unexpectedSpaceAfter', + data: { + type: operator + }, line: 1, column: 33 } From 49feb837aa4e335fbb52a14a9d4c352099a24bd4 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 4 Feb 2019 23:12:50 -0800 Subject: [PATCH 71/92] fixed up tests and build --- .../eslint-plugin/src/rules/no-unused-vars.ts | 4 +++- .../rules/type-annotation-spacing.test.ts | 18 +++++++++--------- packages/eslint-plugin/typings/eslint.d.ts | 9 --------- packages/eslint-plugin/typings/ts-eslint.d.ts | 1 + packages/parser/tsconfig.json | 2 +- 5 files changed, 14 insertions(+), 20 deletions(-) delete mode 100644 packages/eslint-plugin/typings/eslint.d.ts diff --git a/packages/eslint-plugin/src/rules/no-unused-vars.ts b/packages/eslint-plugin/src/rules/no-unused-vars.ts index 0ad34e3e01e4..8097d8dcc379 100644 --- a/packages/eslint-plugin/src/rules/no-unused-vars.ts +++ b/packages/eslint-plugin/src/rules/no-unused-vars.ts @@ -102,7 +102,9 @@ const rule: RuleModule = { const { variableScope } = scope; if (variableScope !== scope) { const superVar = variableScope.set.get(node.name); - if (superVar) superVar.eslintUsed = true; + if (superVar) { + superVar.eslintUsed = true; + } } } }); diff --git a/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts index 026af50f6ca3..07ae28a379d0 100644 --- a/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts @@ -3583,7 +3583,7 @@ type Foo = { { messageId: 'expectedSpaceBefore', data: { - type: '.' + type: ':' }, line: 3, column: 30 @@ -3591,7 +3591,7 @@ type Foo = { { messageId: 'expectedSpaceBefore', data: { - type: '.' + type: ':' }, line: 3, column: 45 @@ -3599,7 +3599,7 @@ type Foo = { { messageId: 'expectedSpaceBefore', data: { - type: '.' + type: ':' }, line: 3, column: 52 @@ -3607,7 +3607,7 @@ type Foo = { { messageId: 'expectedSpaceBefore', data: { - type: '.' + type: ':' }, line: 4, column: 47 @@ -3615,7 +3615,7 @@ type Foo = { { messageId: 'expectedSpaceBefore', data: { - type: '.' + type: ':' }, line: 4, column: 62 @@ -3623,7 +3623,7 @@ type Foo = { { messageId: 'expectedSpaceBefore', data: { - type: '.' + type: ':' }, line: 4, column: 69 @@ -3631,7 +3631,7 @@ type Foo = { { messageId: 'expectedSpaceBefore', data: { - type: '.' + type: ':' }, line: 5, column: 45 @@ -3639,7 +3639,7 @@ type Foo = { { messageId: 'expectedSpaceBefore', data: { - type: '.' + type: ':' }, line: 5, column: 60 @@ -3647,7 +3647,7 @@ type Foo = { { messageId: 'expectedSpaceBefore', data: { - type: '.' + type: ':' }, line: 5, column: 67 diff --git a/packages/eslint-plugin/typings/eslint.d.ts b/packages/eslint-plugin/typings/eslint.d.ts deleted file mode 100644 index 30ee0180c31d..000000000000 --- a/packages/eslint-plugin/typings/eslint.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -// module augmentation is weird -import { Scope } from 'eslint'; -declare module 'eslint' { - namespace Scope { - interface Variable { - eslintUsed: boolean; - } - } -} diff --git a/packages/eslint-plugin/typings/ts-eslint.d.ts b/packages/eslint-plugin/typings/ts-eslint.d.ts index 37cb9c1bbdea..542fa8f48334 100644 --- a/packages/eslint-plugin/typings/ts-eslint.d.ts +++ b/packages/eslint-plugin/typings/ts-eslint.d.ts @@ -443,6 +443,7 @@ declare module 'ts-eslint' { references: Reference[]; defs: Definition[]; scope: Scope; + eslintUsed?: boolean; } interface Scope { diff --git a/packages/parser/tsconfig.json b/packages/parser/tsconfig.json index d74357950e9c..cd77082d618e 100644 --- a/packages/parser/tsconfig.json +++ b/packages/parser/tsconfig.json @@ -2,7 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "declaration": true, - "outDir": "./dist" + "outDir": "./dist", }, "include": ["src"] } From 6ec6b5fcc48429ad9a919f7480d606cd9045e700 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 4 Feb 2019 23:24:00 -0800 Subject: [PATCH 72/92] fix build error --- .../eslint-plugin/src/rules/no-parameter-properties.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/eslint-plugin/src/rules/no-parameter-properties.ts b/packages/eslint-plugin/src/rules/no-parameter-properties.ts index 02526fe71659..e9ce3d4638af 100644 --- a/packages/eslint-plugin/src/rules/no-parameter-properties.ts +++ b/packages/eslint-plugin/src/rules/no-parameter-properties.ts @@ -104,6 +104,14 @@ const rule: RuleModule = { const modifiers = getModifiers(node); if (allows.indexOf(modifiers) === -1) { + // HAS to be an identifier or assignment or TSC will throw + if ( + node.parameter.type !== AST_NODE_TYPES.Identifier && + node.parameter.type !== AST_NODE_TYPES.AssignmentPattern + ) { + return; + } + const name = node.parameter.type === AST_NODE_TYPES.Identifier ? node.parameter.name From bf3105550ed5b3214f5b9dce16c1d2bfc138a594 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Tue, 5 Feb 2019 14:07:20 -0800 Subject: [PATCH 73/92] add typecheck command and fix errors --- azure-pipelines.yml | 6 ++++++ package.json | 1 + packages/eslint-plugin-tslint/package.json | 5 +++-- .../eslint-plugin-tslint/tsconfig.build.json | 7 +++++++ packages/eslint-plugin-tslint/tsconfig.json | 15 +++++++++------ packages/eslint-plugin/package.json | 3 ++- .../src/rules/no-use-before-define.ts | 2 +- packages/eslint-plugin/tests/RuleTester.ts | 14 +++++++++----- .../tests/rules/no-this-alias.test.ts | 7 ++++--- .../tests/rules/no-use-before-define.test.ts | 18 +++++++++--------- packages/eslint-plugin/tsconfig.build.json | 6 ++++-- packages/eslint-plugin/tsconfig.json | 4 ++-- packages/parser/package.json | 5 +++-- packages/parser/src/parser.ts | 2 +- packages/parser/tsconfig.build.json | 8 ++++++++ packages/parser/tsconfig.json | 15 +++++++++------ packages/typescript-estree/package.json | 6 ++++-- packages/typescript-estree/tsconfig.build.json | 7 +++++++ packages/typescript-estree/tsconfig.json | 12 ++++++------ tsconfig.json | 3 +++ yarn.lock | 14 ++++++++++++++ 21 files changed, 112 insertions(+), 48 deletions(-) create mode 100644 packages/eslint-plugin-tslint/tsconfig.build.json create mode 100644 packages/parser/tsconfig.build.json create mode 100644 packages/typescript-estree/tsconfig.build.json diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 805b5c0a1ee9..eee318c9eb88 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -17,6 +17,12 @@ jobs: # bootstrap yarn --ignore-engines --frozen-lockfile + - script: | + # Note that this command *also* typechecks tests/tools, + # whereas the build only checks src files + yarn typecheck + displayName: 'Typecheck all packages' + - script: | yarn check-format displayName: 'Check code formatting' diff --git a/package.json b/package.json index 8610c6e038be..d260d3fcd456 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "test": "lerna run test --parallel", "build": "lerna run build", "clean": "lerna clean && lerna run clean", + "typecheck": "lerna run typecheck", "lint": "eslint . --ext .js,.ts", "lint-fix": "eslint . --ext .js,.ts --fix", "cz": "git-cz", diff --git a/packages/eslint-plugin-tslint/package.json b/packages/eslint-plugin-tslint/package.json index 59b66dd7b153..d27cdb6ab887 100644 --- a/packages/eslint-plugin-tslint/package.json +++ b/packages/eslint-plugin-tslint/package.json @@ -21,8 +21,9 @@ "scripts": { "test": "jest --coverage", "prebuild": "npm run clean", - "build": "tsc", - "clean": "rimraf dist/" + "build": "tsc -p tsconfig.build.json", + "clean": "rimraf dist/", + "typecheck": "tsc --noEmit" }, "dependencies": { "lodash.memoize": "^4.1.2" diff --git a/packages/eslint-plugin-tslint/tsconfig.build.json b/packages/eslint-plugin-tslint/tsconfig.build.json new file mode 100644 index 000000000000..b89aec90074d --- /dev/null +++ b/packages/eslint-plugin-tslint/tsconfig.build.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + }, + "include": ["src"], +} diff --git a/packages/eslint-plugin-tslint/tsconfig.json b/packages/eslint-plugin-tslint/tsconfig.json index d74357950e9c..b86222d3cccc 100644 --- a/packages/eslint-plugin-tslint/tsconfig.json +++ b/packages/eslint-plugin-tslint/tsconfig.json @@ -1,8 +1,11 @@ { - "extends": "../../tsconfig.json", - "compilerOptions": { - "declaration": true, - "outDir": "./dist" - }, - "include": ["src"] + "extends": "./tsconfig.build.json", + "include": [ + "src", + "tests", + ], + "exclude": [ + "tests/test-project", + "tests/test-tslint-rules-directory", + ], } diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 4fbc72a2b384..b81adb103f69 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -31,7 +31,8 @@ "recommended:update": "ts-node tools/update-recommended.ts", "prebuild": "npm run clean", "build": "tsc -p tsconfig.build.json", - "clean": "rimraf dist/" + "clean": "rimraf dist/", + "typecheck": "tsc --noEmit" }, "dependencies": { "@typescript-eslint/parser": "1.2.0", diff --git a/packages/eslint-plugin/src/rules/no-use-before-define.ts b/packages/eslint-plugin/src/rules/no-use-before-define.ts index e48d76f45a18..82ccc76721e7 100644 --- a/packages/eslint-plugin/src/rules/no-use-before-define.ts +++ b/packages/eslint-plugin/src/rules/no-use-before-define.ts @@ -161,7 +161,7 @@ interface Config { variables?: boolean; typedefs?: boolean; } -type Options = [Config]; +type Options = ['nofunc' | Config]; type MessageIds = 'noUseBeforeDefine'; const defaultOptions: Options = [ diff --git a/packages/eslint-plugin/tests/RuleTester.ts b/packages/eslint-plugin/tests/RuleTester.ts index f6bdcaef40ef..37a4867fb75b 100644 --- a/packages/eslint-plugin/tests/RuleTester.ts +++ b/packages/eslint-plugin/tests/RuleTester.ts @@ -1,12 +1,13 @@ import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; -import { RuleTester, Linter } from 'eslint'; +import { RuleTester } from 'eslint'; import RuleModule from 'ts-eslint'; +import { ParserOptions } from '@typescript-eslint/parser'; interface ValidTestCase { code: string; - readonly options?: TOptions; + options?: TOptions; filename?: string; - parserOptions?: Linter.ParserOptions; + parserOptions?: ParserOptions; settings?: Record; parser?: string; globals?: Record; @@ -15,7 +16,7 @@ interface ValidTestCase { interface InvalidTestCase extends ValidTestCase { errors: TestCaseError[]; - output?: string | null; + output?: string; } interface TestCaseError { @@ -43,7 +44,10 @@ declare class RuleTesterTyped { } const RuleTesterRetyped = (RuleTester as any) as { - new (config?: any): RuleTesterTyped; + new (config?: { + parser: '@typescript-eslint/parser'; + parserOptions?: ParserOptions; + }): RuleTesterTyped; }; export default RuleTesterRetyped; export { RunTests, TestCaseError, InvalidTestCase, ValidTestCase }; diff --git a/packages/eslint-plugin/tests/rules/no-this-alias.test.ts b/packages/eslint-plugin/tests/rules/no-this-alias.test.ts index 87ff3651e0f9..1573d23f9039 100644 --- a/packages/eslint-plugin/tests/rules/no-this-alias.test.ts +++ b/packages/eslint-plugin/tests/rules/no-this-alias.test.ts @@ -8,20 +8,21 @@ // Requirements //------------------------------------------------------------------------------ +import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; import rule from '../../src/rules/no-this-alias'; import RuleTester from '../RuleTester'; const idError = { messageId: 'thisAssignment' as 'thisAssignment', - type: 'Identifier' + type: AST_NODE_TYPES.Identifier }; const destructureError = { messageId: 'thisDestructure' as 'thisDestructure', - type: 'ObjectPattern' + type: AST_NODE_TYPES.ObjectPattern }; const arrayDestructureError = { messageId: 'thisDestructure' as 'thisDestructure', - type: 'ArrayPattern' + type: AST_NODE_TYPES.ArrayPattern }; //------------------------------------------------------------------------------ diff --git a/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts b/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts index 13dd9f329194..0e81aa408ca9 100644 --- a/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts +++ b/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts @@ -8,7 +8,7 @@ // Requirements //------------------------------------------------------------------------------ -import rule, { Options } from '../../src/rules/no-use-before-define'; +import rule from '../../src/rules/no-use-before-define'; import RuleTester from '../RuleTester'; import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; @@ -41,7 +41,7 @@ const x: Foo = {}; a(); function a() { alert(arguments); } `, - options: ['nofunc'] as Options + options: ['nofunc'] }, { code: '(() => { var a = 42; alert(a); })();', @@ -104,7 +104,7 @@ a(); function a() {} } `, - options: ['nofunc'] as Options, + options: ['nofunc'], parserOptions }, { @@ -236,7 +236,7 @@ export namespace Third { a++; var a=19; `, - parserOptions: { sourceType: 'module' as 'module' }, + parserOptions: { sourceType: 'module' }, errors: [ { messageId: 'noUseBeforeDefine', @@ -252,7 +252,7 @@ var a=19; a++; var a=19; `, - parserOptions: { parserOptions }, + parserOptions, errors: [ { messageId: 'noUseBeforeDefine', @@ -340,7 +340,7 @@ a(); var a=function() {}; `, - options: ['nofunc'] as Options, + options: ['nofunc'], errors: [ { messageId: 'noUseBeforeDefine', @@ -631,7 +631,7 @@ var a=function() {}; new A(); var A = class {}; `, - options: [{ classes: false }] as Options, + options: [{ classes: false }], parserOptions, errors: [ { @@ -650,7 +650,7 @@ function foo() { } var A = class {}; `, - options: [{ classes: false }] as Options, + options: [{ classes: false }], parserOptions, errors: [ { @@ -829,7 +829,7 @@ function foo() { var bar; `, parserOptions, - options: [{ variables: false }] as Options, + options: [{ variables: false }], errors: [ { messageId: 'noUseBeforeDefine', diff --git a/packages/eslint-plugin/tsconfig.build.json b/packages/eslint-plugin/tsconfig.build.json index b2fcd92b4b8b..c284ed71fc99 100644 --- a/packages/eslint-plugin/tsconfig.build.json +++ b/packages/eslint-plugin/tsconfig.build.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", "compilerOptions": { + // specifically disable declarations for the plugin "declaration": false, + "declarationMap": false, "outDir": "./dist", - "resolveJsonModule": true + "resolveJsonModule": true, }, - "include": ["src", "typings"] + "include": ["src", "typings"], } diff --git a/packages/eslint-plugin/tsconfig.json b/packages/eslint-plugin/tsconfig.json index 7418d4448682..52a6a092b0a3 100644 --- a/packages/eslint-plugin/tsconfig.json +++ b/packages/eslint-plugin/tsconfig.json @@ -4,6 +4,6 @@ "src", "typings", "tests", - "tools" - ] + "tools", + ], } diff --git a/packages/parser/package.json b/packages/parser/package.json index 26de602491a7..2e376b38f2d0 100644 --- a/packages/parser/package.json +++ b/packages/parser/package.json @@ -27,9 +27,10 @@ ], "scripts": { "prebuild": "npm run clean", - "build": "tsc", + "build": "tsc -p tsconfig.build.json", "clean": "rimraf dist/", - "test": "jest --coverage" + "test": "jest --coverage", + "typecheck": "tsc --noEmit" }, "peerDependencies": { "eslint": "^5.0.0", diff --git a/packages/parser/src/parser.ts b/packages/parser/src/parser.ts index 4031aef72762..ebf1eb6e30d2 100644 --- a/packages/parser/src/parser.ts +++ b/packages/parser/src/parser.ts @@ -114,4 +114,4 @@ export function parseForESLint( return { ast, services, scopeManager, visitorKeys }; } -export { ParserServices }; +export { ParserServices, ParserOptions }; diff --git a/packages/parser/tsconfig.build.json b/packages/parser/tsconfig.build.json new file mode 100644 index 000000000000..1e3450ecc1e8 --- /dev/null +++ b/packages/parser/tsconfig.build.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "declaration": true, + "outDir": "./dist", + }, + "include": ["src"], +} diff --git a/packages/parser/tsconfig.json b/packages/parser/tsconfig.json index cd77082d618e..079001c0aa01 100644 --- a/packages/parser/tsconfig.json +++ b/packages/parser/tsconfig.json @@ -1,8 +1,11 @@ { - "extends": "../../tsconfig.json", - "compilerOptions": { - "declaration": true, - "outDir": "./dist", - }, - "include": ["src"] + "extends": "./tsconfig.build.json", + "include": [ + "src", + "tests", + "tools", + ], + "exclude": [ + "tests/fixtures", + ], } diff --git a/packages/typescript-estree/package.json b/packages/typescript-estree/package.json index 50432ba4d214..71a99bf16e96 100644 --- a/packages/typescript-estree/package.json +++ b/packages/typescript-estree/package.json @@ -28,11 +28,12 @@ ], "scripts": { "prebuild": "npm run clean", - "build": "tsc", + "build": "tsc -p tsconfig.build.json", "clean": "rimraf dist/", "test": "jest --coverage", "unit-tests": "jest \"./tests/lib/.*\"", - "ast-alignment-tests": "jest spec.ts" + "ast-alignment-tests": "jest spec.ts", + "typecheck": "tsc --noEmit" }, "dependencies": { "lodash.unescape": "4.0.1", @@ -42,6 +43,7 @@ "typescript": "*" }, "devDependencies": { + "@babel/types": "^7.3.2", "@typescript-eslint/shared-fixtures": "1.2.0" } } diff --git a/packages/typescript-estree/tsconfig.build.json b/packages/typescript-estree/tsconfig.build.json new file mode 100644 index 000000000000..b89aec90074d --- /dev/null +++ b/packages/typescript-estree/tsconfig.build.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + }, + "include": ["src"], +} diff --git a/packages/typescript-estree/tsconfig.json b/packages/typescript-estree/tsconfig.json index d74357950e9c..33e188f86981 100644 --- a/packages/typescript-estree/tsconfig.json +++ b/packages/typescript-estree/tsconfig.json @@ -1,8 +1,8 @@ { - "extends": "../../tsconfig.json", - "compilerOptions": { - "declaration": true, - "outDir": "./dist" - }, - "include": ["src"] + "extends": "./tsconfig.build.json", + "include": [ + "src", + "tests", + "tools", + ], } diff --git a/tsconfig.json b/tsconfig.json index d6b0130a25ad..1c0243d8bb15 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,6 +3,8 @@ "allowSyntheticDefaultImports": true, "allowUnreachableCode": false, "allowUnusedLabels": false, + "declaration": true, + "declarationMap": true, "esModuleInterop": true, "module": "commonjs", "moduleResolution": "node", @@ -10,6 +12,7 @@ "noUnusedLocals": true, "noUnusedParameters": true, "pretty": true, + "sourceMap": true, "strict": true, "target": "es2017", } diff --git a/yarn.lock b/yarn.lock index a6fce7f4d71d..c6033ff8b110 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23,6 +23,15 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.3.0.tgz#930251fe6714df47ce540a919ccdf6dcfb652b61" integrity sha512-8M30TzMpLHGmuthHZStm4F+az5wxyYeh8U+LWK7+b2qnlQ0anXBmOQ1I8DCMV1K981wPY3C3kWZ4SA1lR3Y3xQ== +"@babel/types@^7.3.2": + version "7.3.2" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.3.2.tgz#424f5be4be633fff33fb83ab8d67e4a8290f5a2f" + integrity sha512-3Y6H8xlUlpbGR+XvawiH0UXehqydTmNmEpozWcXymqwcrwYAl5KMvKtQ+TF6f6E08V6Jur7v/ykdDSF+WDEIXQ== + dependencies: + esutils "^2.0.2" + lodash "^4.17.10" + to-fast-properties "^2.0.0" + "@commitlint/cli@^7.1.2", "@commitlint/cli@^7.3.2": version "7.3.2" resolved "https://registry.yarnpkg.com/@commitlint/cli/-/cli-7.3.2.tgz#61abf30b48861e4fbd521690e6d4a3e1258980bb" @@ -6865,6 +6874,11 @@ to-fast-properties@^1.0.3: resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" From a294ea9390bb3a07e30ede9390bfe61e47564072 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Wed, 6 Feb 2019 08:50:21 -0800 Subject: [PATCH 74/92] move tsestree-utils into utils --- .../src/rules/adjacent-overload-signatures.ts | 5 +-- packages/eslint-plugin/src/rules/camelcase.ts | 8 +--- .../rules/explicit-member-accessibility.ts | 5 +-- packages/eslint-plugin/src/rules/indent.ts | 10 ++--- .../eslint-plugin/src/rules/member-naming.ts | 3 +- .../src/rules/member-ordering.ts | 5 +-- .../eslint-plugin/src/rules/no-unused-vars.ts | 8 +--- .../src/rules/no-useless-constructor.ts | 10 ++--- packages/eslint-plugin/src/tsestree-utils.ts | 35 ---------------- packages/eslint-plugin/src/util.ts | 42 ++++++++++++++++++- 10 files changed, 58 insertions(+), 73 deletions(-) delete mode 100644 packages/eslint-plugin/src/tsestree-utils.ts diff --git a/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts b/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts index ba1e7c6f1763..ec51bd3755ee 100644 --- a/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts +++ b/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts @@ -6,7 +6,6 @@ import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; -import { getNameFromPropertyName } from '../tsestree-utils'; //------------------------------------------------------------------------------ // Rule Definition @@ -69,13 +68,13 @@ const rule: RuleModule = { case AST_NODE_TYPES.FunctionDeclaration: return member.id && member.id.name; case AST_NODE_TYPES.TSMethodSignature: - return getNameFromPropertyName(member.key); + return util.getNameFromPropertyName(member.key); case AST_NODE_TYPES.TSCallSignatureDeclaration: return 'call'; case AST_NODE_TYPES.TSConstructSignatureDeclaration: return 'new'; case AST_NODE_TYPES.MethodDefinition: - return getNameFromPropertyName(member.key); + return util.getNameFromPropertyName(member.key); } return null; diff --git a/packages/eslint-plugin/src/rules/camelcase.ts b/packages/eslint-plugin/src/rules/camelcase.ts index 6ba5be25c0c4..5f242b3fd21c 100644 --- a/packages/eslint-plugin/src/rules/camelcase.ts +++ b/packages/eslint-plugin/src/rules/camelcase.ts @@ -7,16 +7,12 @@ import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import baseRule from 'eslint/lib/rules/camelcase'; import * as util from '../util'; -import { - InferOptionsTypeFromRule, - InferMessageIdsTypeFromRule -} from '../tsestree-utils'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -type Options = InferOptionsTypeFromRule; -type MessageIds = InferMessageIdsTypeFromRule; +type Options = util.InferOptionsTypeFromRule; +type MessageIds = util.InferMessageIdsTypeFromRule; const defaultOptions: Options = [ { diff --git a/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts index 342387877ea4..1627a3ae1d5c 100644 --- a/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts +++ b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts @@ -6,7 +6,6 @@ import { TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; -import { getNameFromPropertyName } from '../tsestree-utils'; //------------------------------------------------------------------------------ // Rule Definition @@ -54,7 +53,7 @@ const rule: RuleModule = { messageId: 'missingAccessibility', data: { type: 'method definition', - name: getNameFromPropertyName(methodDefinition.key) + name: util.getNameFromPropertyName(methodDefinition.key) } }); } @@ -76,7 +75,7 @@ const rule: RuleModule = { messageId: 'missingAccessibility', data: { type: 'class property', - name: getNameFromPropertyName(classProperty.key) + name: util.getNameFromPropertyName(classProperty.key) } }); } diff --git a/packages/eslint-plugin/src/rules/indent.ts b/packages/eslint-plugin/src/rules/indent.ts index 904775485121..d579074e46c0 100644 --- a/packages/eslint-plugin/src/rules/indent.ts +++ b/packages/eslint-plugin/src/rules/indent.ts @@ -7,19 +7,15 @@ */ import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; -import baseRule from 'eslint/lib/rules/indent'; import RuleModule from 'ts-eslint'; +import baseRule from 'eslint/lib/rules/indent'; import * as util from '../util'; -import { - InferOptionsTypeFromRule, - InferMessageIdsTypeFromRule -} from '../tsestree-utils'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -type Options = InferOptionsTypeFromRule; -type MessageIds = InferMessageIdsTypeFromRule; +type Options = util.InferOptionsTypeFromRule; +type MessageIds = util.InferMessageIdsTypeFromRule; type Range = [number, number]; const KNOWN_NODES = new Set([ diff --git a/packages/eslint-plugin/src/rules/member-naming.ts b/packages/eslint-plugin/src/rules/member-naming.ts index a656f2c8c5e8..bf322d5937ed 100644 --- a/packages/eslint-plugin/src/rules/member-naming.ts +++ b/packages/eslint-plugin/src/rules/member-naming.ts @@ -6,7 +6,6 @@ import { TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; -import { getNameFromPropertyName } from '../tsestree-utils'; //------------------------------------------------------------------------------ // Rule Definition @@ -87,7 +86,7 @@ const rule: RuleModule = { function validateName( node: TSESTree.MethodDefinition | TSESTree.ClassProperty ): void { - const name = getNameFromPropertyName(node.key); + const name = util.getNameFromPropertyName(node.key); const accessibility: Modifiers = node.accessibility || 'public'; const convention = conventions[accessibility]; diff --git a/packages/eslint-plugin/src/rules/member-ordering.ts b/packages/eslint-plugin/src/rules/member-ordering.ts index 994a40aea407..861972b7d056 100644 --- a/packages/eslint-plugin/src/rules/member-ordering.ts +++ b/packages/eslint-plugin/src/rules/member-ordering.ts @@ -6,7 +6,6 @@ import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import * as util from '../util'; -import { getNameFromPropertyName } from '../tsestree-utils'; //------------------------------------------------------------------------------ // Rule Definition @@ -225,11 +224,11 @@ const rule: RuleModule = { case AST_NODE_TYPES.TSPropertySignature: case AST_NODE_TYPES.TSMethodSignature: case AST_NODE_TYPES.ClassProperty: - return getNameFromPropertyName(node.key); + return util.getNameFromPropertyName(node.key); case AST_NODE_TYPES.MethodDefinition: return node.kind === 'constructor' ? 'constructor' - : getNameFromPropertyName(node.key); + : util.getNameFromPropertyName(node.key); case AST_NODE_TYPES.TSConstructSignatureDeclaration: return 'new'; default: diff --git a/packages/eslint-plugin/src/rules/no-unused-vars.ts b/packages/eslint-plugin/src/rules/no-unused-vars.ts index 8097d8dcc379..5c0a10a8e4e2 100644 --- a/packages/eslint-plugin/src/rules/no-unused-vars.ts +++ b/packages/eslint-plugin/src/rules/no-unused-vars.ts @@ -7,17 +7,13 @@ import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/typescript-estree'; import RuleModule from 'ts-eslint'; import baseRule from 'eslint/lib/rules/no-unused-vars'; import * as util from '../util'; -import { - InferMessageIdsTypeFromRule, - InferOptionsTypeFromRule -} from '../tsestree-utils'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -type Options = InferOptionsTypeFromRule; -type MessageIds = InferMessageIdsTypeFromRule; +type Options = util.InferOptionsTypeFromRule; +type MessageIds = util.InferMessageIdsTypeFromRule; const rule: RuleModule = { meta: { diff --git a/packages/eslint-plugin/src/rules/no-useless-constructor.ts b/packages/eslint-plugin/src/rules/no-useless-constructor.ts index c7426aab428f..d5ba1f5a8f13 100644 --- a/packages/eslint-plugin/src/rules/no-useless-constructor.ts +++ b/packages/eslint-plugin/src/rules/no-useless-constructor.ts @@ -4,19 +4,15 @@ */ import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; +import RuleModule from 'ts-eslint'; import baseRule from 'eslint/lib/rules/no-useless-constructor'; import * as util from '../util'; -import { - InferOptionsTypeFromRule, - InferMessageIdsTypeFromRule -} from '../tsestree-utils'; -import RuleModule from 'ts-eslint'; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -type Options = InferOptionsTypeFromRule; -type MessageIds = InferMessageIdsTypeFromRule; +type Options = util.InferOptionsTypeFromRule; +type MessageIds = util.InferMessageIdsTypeFromRule; /** * Check if method with accessibility is not useless diff --git a/packages/eslint-plugin/src/tsestree-utils.ts b/packages/eslint-plugin/src/tsestree-utils.ts deleted file mode 100644 index f4d7e785cb8d..000000000000 --- a/packages/eslint-plugin/src/tsestree-utils.ts +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @fileoverview Utilities for working with union types exported by the TSESTree types - */ - -import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; - -export function getNameFromPropertyName( - propertyName: TSESTree.PropertyName -): string { - if (propertyName.type === AST_NODE_TYPES.Identifier) { - return propertyName.name; - } - return `${propertyName.value}`; -} - -type InferOptionsTypeFromRuleNever = T extends RuleModule< - never, - infer TOptions -> - ? TOptions - : unknown; -export type InferOptionsTypeFromRule = T extends RuleModule< - any, - infer TOptions -> - ? TOptions - : InferOptionsTypeFromRuleNever; - -export type InferMessageIdsTypeFromRule = T extends RuleModule< - infer TMessageIds, - any -> - ? TMessageIds - : unknown; diff --git a/packages/eslint-plugin/src/util.ts b/packages/eslint-plugin/src/util.ts index 3ae3d06a0daa..d1342ad3c5ae 100644 --- a/packages/eslint-plugin/src/util.ts +++ b/packages/eslint-plugin/src/util.ts @@ -1,5 +1,6 @@ +import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; import { ParserServices } from '@typescript-eslint/parser'; -import { RuleContext } from 'ts-eslint'; +import RuleModule, { RuleContext } from 'ts-eslint'; // note - cannot migrate this to an import statement because it will make TSC copy the package.json to the dist folder const version = require('../package.json').version; @@ -149,3 +150,42 @@ export function getParserServices< } return context.parserServices as RequiredParserServices; } + +/** + * Gets a string name representation of the given PropertyName node + */ +export function getNameFromPropertyName( + propertyName: TSESTree.PropertyName +): string { + if (propertyName.type === AST_NODE_TYPES.Identifier) { + return propertyName.name; + } + return `${propertyName.value}`; +} + +type InferOptionsTypeFromRuleNever = T extends RuleModule< + never, + infer TOptions +> + ? TOptions + : unknown; +/** + * Uses type inference to fetch the TOptions type from the given RuleModule + */ +export type InferOptionsTypeFromRule = T extends RuleModule< + any, + infer TOptions +> + ? TOptions + : InferOptionsTypeFromRuleNever; + +/** + * Uses type inference to fetch the TMessageIds type from the given RuleModule + */ +export type InferMessageIdsTypeFromRule = T extends RuleModule< + infer TMessageIds, + any +> + ? TMessageIds + : unknown; + From a49264c1a7d6eea633641c7c49445783a7dcdd36 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Wed, 6 Feb 2019 10:48:43 -0800 Subject: [PATCH 75/92] split utils into separate files to reduce overall file size --- packages/eslint-plugin/src/util.ts | 191 ------------------ .../eslint-plugin/src/util/applyDefault.ts | 35 ++++ packages/eslint-plugin/src/util/deepMerge.ts | 49 +++++ .../src/util/getParserServices.ts | 29 +++ packages/eslint-plugin/src/util/index.ts | 5 + packages/eslint-plugin/src/util/misc.ts | 65 ++++++ 6 files changed, 183 insertions(+), 191 deletions(-) delete mode 100644 packages/eslint-plugin/src/util.ts create mode 100644 packages/eslint-plugin/src/util/applyDefault.ts create mode 100644 packages/eslint-plugin/src/util/deepMerge.ts create mode 100644 packages/eslint-plugin/src/util/getParserServices.ts create mode 100644 packages/eslint-plugin/src/util/index.ts create mode 100644 packages/eslint-plugin/src/util/misc.ts diff --git a/packages/eslint-plugin/src/util.ts b/packages/eslint-plugin/src/util.ts deleted file mode 100644 index d1342ad3c5ae..000000000000 --- a/packages/eslint-plugin/src/util.ts +++ /dev/null @@ -1,191 +0,0 @@ -import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; -import { ParserServices } from '@typescript-eslint/parser'; -import RuleModule, { RuleContext } from 'ts-eslint'; - -// note - cannot migrate this to an import statement because it will make TSC copy the package.json to the dist folder -const version = require('../package.json').version; - -export type ObjectLike = Record; - -export function tslintRule(name: string) { - return `\`${name}\` from TSLint`; -} - -export function metaDocsUrl(name: string) { - return `https://github.com/typescript-eslint/typescript-eslint/blob/${version}/packages/eslint-plugin/docs/rules/${name}.md`; -} - -/** - * Check if the context file name is *.ts or *.tsx - * @param fileName The context file name - * @returns `true` if the file name ends in *.ts or *.tsx - * @private - */ -export function isTypescript(fileName: string) { - return /\.tsx?$/i.test(fileName || ''); -} - -/** - * Check if the context file name is *.d.ts or *.d.ts - * @param fileName The context file name - * @returns `true` if the file name ends in *.d.ts or *.d.ts - * @private - */ -export function isDefinitionFile(fileName: string) { - return /\.d\.tsx?$/i.test(fileName || ''); -} - -/** - * Check if the variable contains an object stricly rejecting arrays - * @param obj an object - * @returns `true` if obj is an object - */ -function isObjectNotArray(obj: T | any[]): obj is T { - return typeof obj === 'object' && !Array.isArray(obj); -} - -/** - * Pure function - doesn't mutate either parameter! - * Merges two objects together deeply, overwriting the properties in first with the properties in second - * @param first The first object - * @param second The second object - * @returns a new object - */ -export function deepMerge( - first: ObjectLike = {}, - second: ObjectLike = {} -): T { - // get the unique set of keys across both objects - const keys = new Set(Object.keys(first).concat(Object.keys(second))); - - return Array.from(keys).reduce( - (acc, key) => { - const firstHasKey = key in first; - const secondHasKey = key in second; - - if (firstHasKey && secondHasKey) { - if (isObjectNotArray(first[key]) && isObjectNotArray(second[key])) { - // object type - acc[key] = deepMerge(first[key], second[key]); - } else { - // value type - acc[key] = second[key]; - } - } else if (firstHasKey) { - acc[key] = first[key]; - } else { - acc[key] = second[key]; - } - - return acc; - }, - {} as T - ); -} - -/** - * Pure function - doesn't mutate either parameter! - * Uses the default options and overrides with the options provided by the user - * @param defaultOptions the defaults - * @param userOptions the user opts - * @returns the options with defaults - */ -export function applyDefault( - defaultOptions: TDefault, - userOptions: TUser | null -): TDefault { - // clone defaults - const options: TDefault = JSON.parse(JSON.stringify(defaultOptions)); - - // eslint-disable-next-line eqeqeq - if (userOptions == null) { - return options; - } - - options.forEach((opt, i) => { - if (userOptions[i]) { - const userOpt = userOptions[i]; - - if (isObjectNotArray(userOpt) && isObjectNotArray(opt)) { - options[i] = deepMerge(opt, userOpt); - } else { - options[i] = userOpt; - } - } - }); - - return options; -} - -/** - * Upper cases the first character or the string - */ -export function upperCaseFirst(str: string) { - return str[0].toUpperCase() + str.slice(1); -} - -type RequiredParserServices = { - [k in keyof ParserServices]: Exclude -}; - -/** - * Try to retrieve typescript parser service from context - */ -export function getParserServices< - TMessageIds extends string, - TOptions extends any[] ->(context: RuleContext): RequiredParserServices { - if ( - !context.parserServices || - !context.parserServices.program || - !context.parserServices.esTreeNodeToTSNodeMap - ) { - /** - * The user needs to have configured "project" in their parserOptions - * for @typescript-eslint/parser - */ - throw new Error( - 'You have used a rule which requires parserServices to be generated. You must therefore provide a value for the "parserOptions.project" property for @typescript-eslint/parser.' - ); - } - return context.parserServices as RequiredParserServices; -} - -/** - * Gets a string name representation of the given PropertyName node - */ -export function getNameFromPropertyName( - propertyName: TSESTree.PropertyName -): string { - if (propertyName.type === AST_NODE_TYPES.Identifier) { - return propertyName.name; - } - return `${propertyName.value}`; -} - -type InferOptionsTypeFromRuleNever = T extends RuleModule< - never, - infer TOptions -> - ? TOptions - : unknown; -/** - * Uses type inference to fetch the TOptions type from the given RuleModule - */ -export type InferOptionsTypeFromRule = T extends RuleModule< - any, - infer TOptions -> - ? TOptions - : InferOptionsTypeFromRuleNever; - -/** - * Uses type inference to fetch the TMessageIds type from the given RuleModule - */ -export type InferMessageIdsTypeFromRule = T extends RuleModule< - infer TMessageIds, - any -> - ? TMessageIds - : unknown; - diff --git a/packages/eslint-plugin/src/util/applyDefault.ts b/packages/eslint-plugin/src/util/applyDefault.ts new file mode 100644 index 000000000000..297792dd834c --- /dev/null +++ b/packages/eslint-plugin/src/util/applyDefault.ts @@ -0,0 +1,35 @@ +import { deepMerge, isObjectNotArray } from './deepMerge'; + +/** + * Pure function - doesn't mutate either parameter! + * Uses the default options and overrides with the options provided by the user + * @param defaultOptions the defaults + * @param userOptions the user opts + * @returns the options with defaults + */ +export function applyDefault( + defaultOptions: TDefault, + userOptions: TUser | null +): TDefault { + // clone defaults + const options: TDefault = JSON.parse(JSON.stringify(defaultOptions)); + + // eslint-disable-next-line eqeqeq + if (userOptions == null) { + return options; + } + + options.forEach((opt, i) => { + if (userOptions[i]) { + const userOpt = userOptions[i]; + + if (isObjectNotArray(userOpt) && isObjectNotArray(opt)) { + options[i] = deepMerge(opt, userOpt); + } else { + options[i] = userOpt; + } + } + }); + + return options; +} diff --git a/packages/eslint-plugin/src/util/deepMerge.ts b/packages/eslint-plugin/src/util/deepMerge.ts new file mode 100644 index 000000000000..9839bd82e569 --- /dev/null +++ b/packages/eslint-plugin/src/util/deepMerge.ts @@ -0,0 +1,49 @@ +export type ObjectLike = Record; + +/** + * Check if the variable contains an object stricly rejecting arrays + * @param obj an object + * @returns `true` if obj is an object + */ +export function isObjectNotArray(obj: T | any[]): obj is T { + return typeof obj === 'object' && !Array.isArray(obj); +} + +/** + * Pure function - doesn't mutate either parameter! + * Merges two objects together deeply, overwriting the properties in first with the properties in second + * @param first The first object + * @param second The second object + * @returns a new object + */ +export function deepMerge( + first: ObjectLike = {}, + second: ObjectLike = {} +): T { + // get the unique set of keys across both objects + const keys = new Set(Object.keys(first).concat(Object.keys(second))); + + return Array.from(keys).reduce( + (acc, key) => { + const firstHasKey = key in first; + const secondHasKey = key in second; + + if (firstHasKey && secondHasKey) { + if (isObjectNotArray(first[key]) && isObjectNotArray(second[key])) { + // object type + acc[key] = deepMerge(first[key], second[key]); + } else { + // value type + acc[key] = second[key]; + } + } else if (firstHasKey) { + acc[key] = first[key]; + } else { + acc[key] = second[key]; + } + + return acc; + }, + {} as T + ); +} diff --git a/packages/eslint-plugin/src/util/getParserServices.ts b/packages/eslint-plugin/src/util/getParserServices.ts new file mode 100644 index 000000000000..6d23a5f24f9b --- /dev/null +++ b/packages/eslint-plugin/src/util/getParserServices.ts @@ -0,0 +1,29 @@ +import { ParserServices } from '@typescript-eslint/parser'; +import { RuleContext } from 'ts-eslint'; + +type RequiredParserServices = { + [k in keyof ParserServices]: Exclude +}; + +/** + * Try to retrieve typescript parser service from context + */ +export function getParserServices< + TMessageIds extends string, + TOptions extends any[] +>(context: RuleContext): RequiredParserServices { + if ( + !context.parserServices || + !context.parserServices.program || + !context.parserServices.esTreeNodeToTSNodeMap + ) { + /** + * The user needs to have configured "project" in their parserOptions + * for @typescript-eslint/parser + */ + throw new Error( + 'You have used a rule which requires parserServices to be generated. You must therefore provide a value for the "parserOptions.project" property for @typescript-eslint/parser.' + ); + } + return context.parserServices as RequiredParserServices; +} diff --git a/packages/eslint-plugin/src/util/index.ts b/packages/eslint-plugin/src/util/index.ts new file mode 100644 index 000000000000..e2565c004440 --- /dev/null +++ b/packages/eslint-plugin/src/util/index.ts @@ -0,0 +1,5 @@ +export * from './applyDefault'; +export * from './createRule'; +export * from './deepMerge'; +export * from './getParserServices'; +export * from './misc'; diff --git a/packages/eslint-plugin/src/util/misc.ts b/packages/eslint-plugin/src/util/misc.ts new file mode 100644 index 000000000000..ab3075c42c4d --- /dev/null +++ b/packages/eslint-plugin/src/util/misc.ts @@ -0,0 +1,65 @@ +/** + * @fileoverview Really small utility functions that didn't deserve their own files + */ + +import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; +import RuleModule from 'ts-eslint'; + +/** + * Check if the context file name is *.ts or *.tsx + */ +export function isTypescript(fileName: string) { + return /\.tsx?$/i.test(fileName || ''); +} + +/** + * Check if the context file name is *.d.ts or *.d.tsx + */ +export function isDefinitionFile(fileName: string) { + return /\.d\.tsx?$/i.test(fileName || ''); +} + +/** + * Upper cases the first character or the string + */ +export function upperCaseFirst(str: string) { + return str[0].toUpperCase() + str.slice(1); +} + +type InferOptionsTypeFromRuleNever = T extends RuleModule< + never, + infer TOptions +> + ? TOptions + : unknown; +/** + * Uses type inference to fetch the TOptions type from the given RuleModule + */ +export type InferOptionsTypeFromRule = T extends RuleModule< + any, + infer TOptions +> + ? TOptions + : InferOptionsTypeFromRuleNever; + +/** + * Uses type inference to fetch the TMessageIds type from the given RuleModule + */ +export type InferMessageIdsTypeFromRule = T extends RuleModule< + infer TMessageIds, + any +> + ? TMessageIds + : unknown; + +/** + * Gets a string name representation of the given PropertyName node + */ +export function getNameFromPropertyName( + propertyName: TSESTree.PropertyName +): string { + if (propertyName.type === AST_NODE_TYPES.Identifier) { + return propertyName.name; + } + return `${propertyName.value}`; +} From 46dd1e5a0724e4e0401340d4e293832d7ee4b753 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Wed, 6 Feb 2019 10:53:13 -0800 Subject: [PATCH 76/92] add a createRule helper function makes the rule creation process more ergonomic and gives us more control --- .../src/rules/adjacent-overload-signatures.ts | 27 +---- .../eslint-plugin/src/rules/array-type.ts | 25 +---- packages/eslint-plugin/src/rules/ban-types.ts | 83 ++++++-------- packages/eslint-plugin/src/rules/camelcase.ts | 31 ++--- .../src/rules/class-name-casing.ts | 30 +---- .../rules/explicit-function-return-type.ts | 35 ++---- .../rules/explicit-member-accessibility.ts | 27 +---- .../src/rules/generic-type-naming.ts | 26 ++--- packages/eslint-plugin/src/rules/indent.ts | 51 ++++----- .../src/rules/interface-name-prefix.ts | 28 +---- .../src/rules/member-delimiter-style.ts | 50 +++------ .../eslint-plugin/src/rules/member-naming.ts | 28 +---- .../src/rules/member-ordering.ts | 106 ++++++++---------- .../rules/no-angle-bracket-type-assertion.ts | 24 +--- .../src/rules/no-array-constructor.ts | 19 +--- .../src/rules/no-empty-interface.ts | 44 +++----- .../src/rules/no-explicit-any.ts | 20 +--- .../src/rules/no-extraneous-class.ts | 39 ++----- .../src/rules/no-inferrable-types.ts | 36 ++---- .../eslint-plugin/src/rules/no-misused-new.ts | 24 +--- .../eslint-plugin/src/rules/no-namespace.ts | 38 ++----- .../src/rules/no-non-null-assertion.ts | 23 +--- .../rules/no-object-literal-type-assertion.ts | 36 ++---- .../src/rules/no-parameter-properties.ts | 37 ++---- .../eslint-plugin/src/rules/no-this-alias.ts | 36 ++---- .../src/rules/no-triple-slash-reference.ts | 28 +---- .../eslint-plugin/src/rules/no-type-alias.ts | 52 +++------ .../rules/no-unnecessary-type-assertion.ts | 22 +--- .../eslint-plugin/src/rules/no-unused-vars.ts | 23 +--- .../src/rules/no-use-before-define.ts | 42 +++---- .../src/rules/no-useless-constructor.ts | 20 +--- .../src/rules/no-var-requires.ts | 20 +--- .../src/rules/prefer-interface.ts | 22 +--- .../src/rules/prefer-namespace-keyword.ts | 22 +--- .../src/rules/restrict-plus-operands.ts | 26 ++--- .../src/rules/type-annotation-spacing.ts | 37 ++---- packages/eslint-plugin/src/util/createRule.ts | 61 ++++++++++ packages/eslint-plugin/tests/RuleTester.ts | 15 ++- .../tests/rules/ban-types.test.ts | 5 +- .../eslint-plugin/tests/rules/indent.test.ts | 9 +- .../rules/type-annotation-spacing.test.ts | 12 +- packages/eslint-plugin/typings/ts-eslint.d.ts | 67 ++++++----- 42 files changed, 497 insertions(+), 909 deletions(-) create mode 100644 packages/eslint-plugin/src/util/createRule.ts diff --git a/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts b/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts index ec51bd3755ee..f04bbff214ae 100644 --- a/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts +++ b/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts @@ -4,16 +4,8 @@ */ import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -type Options = []; -type MessageIds = 'adjacentSignature'; - type RuleNode = | TSESTree.ClassBody | TSESTree.Program @@ -22,14 +14,14 @@ type RuleNode = | TSESTree.TSInterfaceBody; type Member = TSESTree.ClassElement | TSESTree.Statement | TSESTree.TypeElement; -const rule: RuleModule = { +export default util.createRule({ + name: 'adjacent-overload-signatures', meta: { type: 'suggestion', docs: { description: 'Require that member overloads be consecutive', category: 'Best Practices', - extraDescription: [util.tslintRule('adjacent-overload-signatures')], - url: util.metaDocsUrl('adjacent-overload-signatures'), + tslintName: 'adjacent-overload-signatures', recommended: 'error' }, schema: [], @@ -37,12 +29,8 @@ const rule: RuleModule = { adjacentSignature: "All '{{name}}' signatures should be adjacent." } }, - + defaultOptions: [], create(context) { - //---------------------------------------------------------------------- - // Helpers - //---------------------------------------------------------------------- - /** * Gets the name of the member being processed. * @param member the member being processed. @@ -131,9 +119,6 @@ const rule: RuleModule = { } } - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- return { ClassBody: checkBodyForOverloadMethods, Program: checkBodyForOverloadMethods, @@ -142,6 +127,4 @@ const rule: RuleModule = { TSInterfaceBody: checkBodyForOverloadMethods }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/array-type.ts b/packages/eslint-plugin/src/rules/array-type.ts index 5e637ae4a62c..fe2e3d2fe048 100644 --- a/packages/eslint-plugin/src/rules/array-type.ts +++ b/packages/eslint-plugin/src/rules/array-type.ts @@ -5,7 +5,6 @@ */ import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import * as util from '../util'; /** @@ -73,10 +72,6 @@ function typeNeedsParentheses(node: TSESTree.Node): boolean { } } -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - type Options = ['array' | 'generic' | 'array-simple']; type MessageIds = | 'errorStringGeneric' @@ -84,16 +79,14 @@ type MessageIds = | 'errorStringArray' | 'errorStringArraySimple'; -const defaultOptions: Options = ['array']; - -const rule: RuleModule = { +export default util.createRule({ + name: 'array-type', meta: { type: 'suggestion', docs: { description: 'Requires using either `T[]` or `Array` for arrays', - extraDescription: [util.tslintRule('array-type')], + tslintRuleName: 'array-type', category: 'Stylistic Issues', - url: util.metaDocsUrl('array-type'), recommended: 'error' }, fixable: 'code', @@ -113,8 +106,8 @@ const rule: RuleModule = { } ] }, - create(context) { - const option = util.applyDefault(defaultOptions, context.options)[0]; + defaultOptions: ['array'], + create(context, [option]) { const sourceCode = context.getSourceCode(); /** @@ -149,10 +142,6 @@ const rule: RuleModule = { return 'T'; } - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- - return { TSArrayType(node: TSESTree.TSArrayType) { if ( @@ -254,6 +243,4 @@ const rule: RuleModule = { } }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/ban-types.ts b/packages/eslint-plugin/src/rules/ban-types.ts index 4e64389e5517..c981b9df9d4f 100644 --- a/packages/eslint-plugin/src/rules/ban-types.ts +++ b/packages/eslint-plugin/src/rules/ban-types.ts @@ -4,13 +4,9 @@ */ import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; -import RuleModule, { ReportFixFunction } from 'ts-eslint'; +import { ReportFixFunction } from 'ts-eslint'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - type Options = [ { types: Record< @@ -26,41 +22,14 @@ type Options = [ ]; type MessageIds = 'bannedTypeMessage'; -const defaultOptions: Options = [ - { - types: { - String: { - message: 'Use string instead', - fixWith: 'string' - }, - Boolean: { - message: 'Use boolean instead', - fixWith: 'boolean' - }, - Number: { - message: 'Use number instead', - fixWith: 'number' - }, - Object: { - message: 'Use Record instead', - fixWith: 'Record' - }, - Symbol: { - message: 'Use symbol instead', - fixWith: 'symbol' - } - } - } -]; - -const rule: RuleModule = { +export default util.createRule({ + name: 'ban-types', meta: { type: 'suggestion', docs: { description: 'Enforces that types will not to be used', - extraDescription: [util.tslintRule('ban-types')], + tslintRuleName: 'ban-types', category: 'Best Practices', - url: util.metaDocsUrl('ban-types'), recommended: 'error' }, fixable: 'code', @@ -93,24 +62,42 @@ const rule: RuleModule = { } ] }, - - create(context) { - const banedTypes = util.applyDefault(defaultOptions, context.options)[0] - .types; - - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- - + defaultOptions: [ + { + types: { + String: { + message: 'Use string instead', + fixWith: 'string' + }, + Boolean: { + message: 'Use boolean instead', + fixWith: 'boolean' + }, + Number: { + message: 'Use number instead', + fixWith: 'number' + }, + Object: { + message: 'Use Record instead', + fixWith: 'Record' + }, + Symbol: { + message: 'Use symbol instead', + fixWith: 'symbol' + } + } + } + ], + create(context, [{ types: bannedTypes }]) { return { 'TSTypeReference Identifier'(node: TSESTree.Identifier) { if ( node.parent && node.parent.type !== AST_NODE_TYPES.TSQualifiedName ) { - if (node.name in banedTypes) { + if (node.name in bannedTypes) { let customMessage = ''; - const bannedCfgValue = banedTypes[node.name]; + const bannedCfgValue = bannedTypes[node.name]; let fix: ReportFixFunction | null = null; @@ -140,6 +127,4 @@ const rule: RuleModule = { } }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/camelcase.ts b/packages/eslint-plugin/src/rules/camelcase.ts index 5f242b3fd21c..80cae436b8b9 100644 --- a/packages/eslint-plugin/src/rules/camelcase.ts +++ b/packages/eslint-plugin/src/rules/camelcase.ts @@ -4,38 +4,32 @@ */ import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import baseRule from 'eslint/lib/rules/camelcase'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ type Options = util.InferOptionsTypeFromRule; type MessageIds = util.InferMessageIdsTypeFromRule; -const defaultOptions: Options = [ - { - allow: ['^UNSAFE_'], - ignoreDestructuring: false, - properties: 'never' - } -]; - -const rule: RuleModule = { +export default util.createRule({ + name: 'ban-types', meta: { type: 'suggestion', docs: { description: 'Enforce camelCase naming convention', category: 'Stylistic Issues', - url: util.metaDocsUrl('ban-types'), recommended: 'error' }, schema: baseRule.meta.schema!, messages: baseRule.meta.messages }, - - create(context) { + defaultOptions: [ + { + allow: ['^UNSAFE_'], + ignoreDestructuring: false, + properties: 'never' + } + ], + create(context, [options]) { const rules = baseRule.create(context); const TS_PROPERTY_TYPES = [ 'TSPropertySignature', @@ -44,7 +38,6 @@ const rule: RuleModule = { 'TSAbstractClassProperty' ]; - const options = util.applyDefault(defaultOptions, context.options)[0]; const properties = options.properties; const allow = options.allow!; @@ -126,6 +119,4 @@ const rule: RuleModule = { } }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/class-name-casing.ts b/packages/eslint-plugin/src/rules/class-name-casing.ts index 353bd6616989..870681553767 100644 --- a/packages/eslint-plugin/src/rules/class-name-casing.ts +++ b/packages/eslint-plugin/src/rules/class-name-casing.ts @@ -4,25 +4,17 @@ * @author Armano */ -import RuleModule from 'ts-eslint'; import * as util from '../util'; import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -type Options = []; -type MessageIds = 'notPascalCased'; - -const rule: RuleModule = { +export default util.createRule({ + name: 'class-name-casing', meta: { type: 'suggestion', docs: { description: 'Require PascalCased class and interface names', - extraDescription: [util.tslintRule('class-name')], + tslintRuleName: 'class-name', category: 'Best Practices', - url: util.metaDocsUrl('class-name-casing'), recommended: 'error' }, messages: { @@ -30,14 +22,8 @@ const rule: RuleModule = { }, schema: [] }, - + defaultOptions: [], create(context) { - // variables should be defined here - - //---------------------------------------------------------------------- - // Helpers - //---------------------------------------------------------------------- - /** * Determine if the identifier name is PascalCased * @param name The identifier name @@ -76,10 +62,6 @@ const rule: RuleModule = { }); } - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- - return { 'ClassDeclaration, TSInterfaceDeclaration, ClassExpression'( node: @@ -117,6 +99,4 @@ const rule: RuleModule = { } }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts index eba4bb80f0dc..073c122b31db 100644 --- a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts +++ b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts @@ -4,12 +4,8 @@ */ import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ type Options = [ { allowExpressions?: boolean; @@ -17,20 +13,14 @@ type Options = [ ]; type MessageIds = 'missingReturnType'; -const defaultOptions: Options = [ - { - allowExpressions: true - } -]; - -const rule: RuleModule = { +export default util.createRule({ + name: 'explicit-function-return-type', meta: { type: 'problem', docs: { description: 'Require explicit return types on functions and class methods', category: 'Stylistic Issues', - url: util.metaDocsUrl('explicit-function-return-type'), recommended: 'warn' }, messages: { @@ -48,14 +38,12 @@ const rule: RuleModule = { } ] }, - - create(context) { - const options = util.applyDefault(defaultOptions, context.options)[0]; - - //---------------------------------------------------------------------- - // Helpers - //---------------------------------------------------------------------- - + defaultOptions: [ + { + allowExpressions: true + } + ], + create(context, [options]) { /** * Checks if the parent of a function expression is a constructor. * @param parent The parent of a function expression node @@ -123,15 +111,10 @@ const rule: RuleModule = { checkFunctionReturnType(node); } - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- return { ArrowFunctionExpression: checkFunctionExpressionReturnType, FunctionDeclaration: checkFunctionReturnType, FunctionExpression: checkFunctionExpressionReturnType }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts index 1627a3ae1d5c..c81b6e7891a7 100644 --- a/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts +++ b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts @@ -4,25 +4,17 @@ */ import { TSESTree } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -type Options = []; -type MessageIds = 'missingAccessibility'; - -const rule: RuleModule = { +export default util.createRule({ + name: 'explicit-member-accessibility', meta: { type: 'problem', docs: { description: 'Require explicit accessibility modifiers on class properties and methods', - extraDescription: [util.tslintRule('member-access')], + tslintRuleName: 'member-access', category: 'Best Practices', - url: util.metaDocsUrl('explicit-member-accessibility'), recommended: 'error' }, messages: { @@ -31,12 +23,8 @@ const rule: RuleModule = { }, schema: [] }, - + defaultOptions: [], create(context) { - //---------------------------------------------------------------------- - // Helpers - //---------------------------------------------------------------------- - /** * Checks if a method declaration has an accessibility modifier. * @param methodDefinition The node representing a MethodDefinition. @@ -81,14 +69,9 @@ const rule: RuleModule = { } } - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- return { ClassProperty: checkPropertyAccessibilityModifier, MethodDefinition: checkMethodAccessibilityModifier }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/generic-type-naming.ts b/packages/eslint-plugin/src/rules/generic-type-naming.ts index 6d68a9364cb3..473fa6bc812f 100644 --- a/packages/eslint-plugin/src/rules/generic-type-naming.ts +++ b/packages/eslint-plugin/src/rules/generic-type-naming.ts @@ -3,25 +3,19 @@ */ import { TSESTree } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import * as util from '../util'; type Options = [string?]; type MessageIds = 'paramNotMatchRule'; -const defaultOptions: Options = [ - // Matches: T , TA , TAbc , TA1Bca , T1 , T2 - '^T([A-Z0-9][a-zA-Z0-9]*){0,1}$' -]; - -const rule: RuleModule = { +export default util.createRule({ + name: 'generic-type-naming', meta: { type: 'suggestion', docs: { description: 'Enforces naming of generic type variables', category: 'Stylistic Issues', - recommended: false, - url: util.metaDocsUrl('generic-type-naming') + recommended: false }, messages: { paramNotMatchRule: 'Type parameter {{name}} does not match rule {{rule}}.' @@ -32,10 +26,12 @@ const rule: RuleModule = { } ] }, - - create(context) { - const rule = util.applyDefault(defaultOptions, context.options)[0]!; - const regex = new RegExp(rule); + defaultOptions: [ + // Matches: T , TA , TAbc , TA1Bca , T1 , T2 + '^T([A-Z0-9][a-zA-Z0-9]*){0,1}$' + ], + create(context, [rule]) { + const regex = new RegExp(rule!); return { TSTypeParameter(node: TSESTree.TSTypeParameter) { @@ -54,6 +50,4 @@ const rule: RuleModule = { } }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/indent.ts b/packages/eslint-plugin/src/rules/indent.ts index d579074e46c0..367f2fc6d010 100644 --- a/packages/eslint-plugin/src/rules/indent.ts +++ b/packages/eslint-plugin/src/rules/indent.ts @@ -7,16 +7,11 @@ */ import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import baseRule from 'eslint/lib/rules/indent'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ type Options = util.InferOptionsTypeFromRule; type MessageIds = util.InferMessageIdsTypeFromRule; -type Range = [number, number]; const KNOWN_NODES = new Set([ // Class properties aren't yet supported by eslint... @@ -85,41 +80,39 @@ const KNOWN_NODES = new Set([ 'TSUnionType' ]); -const defaultOptions: Options = [ - // typescript docs and playground use 4 space indent - 4, - { - // typescript docs indent the case from the switch - // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-1-8.html#example-4 - SwitchCase: 1, - flatTernaryExpressions: false, - ignoredNodes: [] - } -]; - -const rule: RuleModule = { +export default util.createRule({ + name: 'indent', meta: { type: 'layout', docs: { description: 'Enforce consistent indentation', - extraDescription: [util.tslintRule('indent')], + tslintRuleName: 'indent', category: 'Stylistic Issues', - recommended: 'error', - url: util.metaDocsUrl('indent') + recommended: 'error' }, fixable: 'whitespace', schema: baseRule.meta!.schema, messages: baseRule.meta!.messages }, - - create(context) { + defaultOptions: [ + // typescript docs and playground use 4 space indent + 4, + { + // typescript docs indent the case from the switch + // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-1-8.html#example-4 + SwitchCase: 1, + flatTernaryExpressions: false, + ignoredNodes: [] + } + ], + create(context, optionsWithDefaults) { // because we extend the base rule, have to update opts on the context // the context defines options as readonly though... const contextWithDefaults: typeof context = Object.create(context, { options: { writable: false, configurable: false, - value: util.applyDefault(defaultOptions, context.options) + value: optionsWithDefaults } }); @@ -254,7 +247,7 @@ const rule: RuleModule = { declarations: [ { type: AST_NODE_TYPES.VariableDeclarator, - range: [id.range[0], moduleReference.range[1]] as Range, + range: [id.range[0], moduleReference.range[1]], loc: { start: id.loc.start, end: moduleReference.loc.end @@ -268,7 +261,7 @@ const rule: RuleModule = { range: [ moduleReference.range[0], moduleReference.range[0] + 'require'.length - ] as Range, + ], loc: { start: moduleReference.loc.start, end: { @@ -370,7 +363,7 @@ const rule: RuleModule = { node.typeAnnotation ? node.typeAnnotation.range[1] : squareBracketStart.range[0] - ] as Range, + ], loc: { start: squareBracketStart.loc.start, end: node.typeAnnotation @@ -449,6 +442,4 @@ const rule: RuleModule = { } }); } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/interface-name-prefix.ts b/packages/eslint-plugin/src/rules/interface-name-prefix.ts index 1d777bf58ba2..0f895774ffbf 100644 --- a/packages/eslint-plugin/src/rules/interface-name-prefix.ts +++ b/packages/eslint-plugin/src/rules/interface-name-prefix.ts @@ -4,25 +4,19 @@ */ import { TSESTree } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ type Options = ['never' | 'always']; type MessageIds = 'noPrefix'; -const defaultOptions: Options = ['never']; - -const rule: RuleModule<'noPrefix', Options> = { +export default util.createRule({ + name: 'interface-name-prefix', meta: { type: 'suggestion', docs: { description: 'Require that interface names be prefixed with `I`', - extraDescription: [util.tslintRule('interface-name')], + tslintRuleName: 'interface-name', category: 'Stylistic Issues', - url: util.metaDocsUrl('interface-name-prefix'), recommended: 'error' }, messages: { @@ -34,15 +28,10 @@ const rule: RuleModule<'noPrefix', Options> = { } ] }, - - create(context) { - const option = util.applyDefault(defaultOptions, context.options)[0]; + defaultOptions: ['never'], + create(context, [option]) { const never = option !== 'always'; - //---------------------------------------------------------------------- - // Helpers - //---------------------------------------------------------------------- - /** * Checks if a string is prefixed with "I". * @param name The string to check @@ -55,9 +44,6 @@ const rule: RuleModule<'noPrefix', Options> = { return /^I[A-Z]/.test(name); } - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- return { TSInterfaceDeclaration(node: TSESTree.TSInterfaceDeclaration): void { if (never) { @@ -78,6 +64,4 @@ const rule: RuleModule<'noPrefix', Options> = { } }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/member-delimiter-style.ts b/packages/eslint-plugin/src/rules/member-delimiter-style.ts index 09d0eff62831..81cbbbfe1c80 100644 --- a/packages/eslint-plugin/src/rules/member-delimiter-style.ts +++ b/packages/eslint-plugin/src/rules/member-delimiter-style.ts @@ -5,13 +5,8 @@ */ import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - type Delimiter = 'comma' | 'none' | 'semi'; interface TypeOptions { delimiter?: Delimiter; @@ -34,19 +29,6 @@ type MessageIds = | 'expectedComma' | 'expectedSemi'; -const defaultOptions: Options = [ - { - multiline: { - delimiter: 'semi', - requireLast: true - }, - singleline: { - delimiter: 'semi', - requireLast: false - } - } -]; - const definition = { type: 'object', properties: { @@ -71,14 +53,14 @@ const definition = { additionalProperties: false }; -const rule: RuleModule = { +export default util.createRule({ + name: 'member-delimiter-style', meta: { type: 'suggestion', docs: { description: 'Require a specific member delimiter style for interfaces and type literals', category: 'Stylistic Issues', - url: util.metaDocsUrl('member-delimiter-style'), recommended: 'error' }, fixable: 'code', @@ -105,10 +87,20 @@ const rule: RuleModule = { } ] }, - - create(context) { + defaultOptions: [ + { + multiline: { + delimiter: 'semi', + requireLast: true + }, + singleline: { + delimiter: 'semi', + requireLast: false + } + } + ], + create(context, [options]) { const sourceCode = context.getSourceCode(); - const options = util.applyDefault(defaultOptions, context.options)[0]; // use the base options as the defaults for the cases const baseOptions = options; @@ -122,10 +114,6 @@ const rule: RuleModule = { overrides.typeLiteral ); - //---------------------------------------------------------------------- - // Helpers - //---------------------------------------------------------------------- - /** * Check the last token in the given member. * @param member the member to be evaluated. @@ -243,15 +231,9 @@ const rule: RuleModule = { }); } - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- - return { TSInterfaceBody: checkMemberSeparatorStyle, TSTypeLiteral: checkMemberSeparatorStyle }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/member-naming.ts b/packages/eslint-plugin/src/rules/member-naming.ts index bf322d5937ed..58524763e5dc 100644 --- a/packages/eslint-plugin/src/rules/member-naming.ts +++ b/packages/eslint-plugin/src/rules/member-naming.ts @@ -4,13 +4,8 @@ */ import { TSESTree } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - interface Config { private?: T; protected?: T; @@ -20,16 +15,14 @@ type Modifiers = keyof Config; type Options = [Config]; type MessageIds = 'incorrectName'; -const defaultOptions: Options = [{}]; - -const rule: RuleModule = { +export default util.createRule({ + name: 'member-naming', meta: { type: 'suggestion', docs: { description: 'Enforces naming conventions for class members by visibility.', category: 'Stylistic Issues', - url: util.metaDocsUrl('member-naming'), recommended: false }, messages: { @@ -61,9 +54,8 @@ const rule: RuleModule = { } ] }, - - create(context) { - const config = util.applyDefault(defaultOptions, context.options)[0]; + defaultOptions: [{}], + create(context, [config]) { const conventions = (Object.keys(config) as Modifiers[]).reduce< Config >((acc, accessibility) => { @@ -72,10 +64,6 @@ const rule: RuleModule = { return acc; }, {}); - //---------------------------------------------------------------------- - // Helpers - //---------------------------------------------------------------------- - /** * Check that the property name matches the convention for its * accessibility. @@ -99,15 +87,9 @@ const rule: RuleModule = { }); } - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- - return { MethodDefinition: validateName, ClassProperty: validateName }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/member-ordering.ts b/packages/eslint-plugin/src/rules/member-ordering.ts index 861972b7d056..f93ddac2ee61 100644 --- a/packages/eslint-plugin/src/rules/member-ordering.ts +++ b/packages/eslint-plugin/src/rules/member-ordering.ts @@ -4,13 +4,8 @@ */ import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - type MessageIds = 'incorrectOrder'; type OrderConfig = string[] | 'never'; type Options = [ @@ -44,56 +39,14 @@ const schemaOptions = ['field', 'method', 'constructor'].reduce( [] ); -const defaultOptions: Options = [ - { - default: [ - 'public-static-field', - 'protected-static-field', - 'private-static-field', - - 'public-instance-field', - 'protected-instance-field', - 'private-instance-field', - - 'public-field', - 'protected-field', - 'private-field', - - 'static-field', - 'instance-field', - - 'field', - - 'constructor', - - 'public-static-method', - 'protected-static-method', - 'private-static-method', - - 'public-instance-method', - 'protected-instance-method', - 'private-instance-method', - - 'public-method', - 'protected-method', - 'private-method', - - 'static-method', - 'instance-method', - - 'method' - ] - } -]; - -const rule: RuleModule = { +export default util.createRule({ + name: 'member-ordering', meta: { type: 'suggestion', docs: { description: 'Require a consistent member declaration order', - extraDescription: [util.tslintRule('member-ordering')], + tslintRuleName: 'member-ordering', category: 'Stylistic Issues', - url: util.metaDocsUrl('member-ordering'), recommended: false }, messages: { @@ -174,19 +127,53 @@ const rule: RuleModule = { } ] }, + defaultOptions: [ + { + default: [ + 'public-static-field', + 'protected-static-field', + 'private-static-field', + + 'public-instance-field', + 'protected-instance-field', + 'private-instance-field', + + 'public-field', + 'protected-field', + 'private-field', + + 'static-field', + 'instance-field', + + 'field', - create(context) { - const options = util.applyDefault(defaultOptions, context.options)[0]; + 'constructor', + 'public-static-method', + 'protected-static-method', + 'private-static-method', + + 'public-instance-method', + 'protected-instance-method', + 'private-instance-method', + + 'public-method', + 'protected-method', + 'private-method', + + 'static-method', + 'instance-method', + + 'method' + ] + } + ], + create(context, [options]) { const functionExpressions = [ 'FunctionExpression', 'ArrowFunctionExpression' ]; - //---------------------------------------------------------------------- - // Helpers - //---------------------------------------------------------------------- - /** * Gets the node type. * @param node the node to be evaluated. @@ -365,9 +352,6 @@ const rule: RuleModule = { } } - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- return { ClassDeclaration(node: TSESTree.ClassDeclaration) { validateMembers( @@ -399,6 +383,4 @@ const rule: RuleModule = { } }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts b/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts index 1a0e030ac124..65ae3cd0d837 100644 --- a/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-angle-bracket-type-assertion.ts @@ -4,25 +4,17 @@ */ import { TSESTree } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -type Options = []; -type MessageIds = 'preferAs'; - -const rule: RuleModule = { +export default util.createRule({ + name: 'no-angle-bracket-type-assertion', meta: { type: 'problem', docs: { description: 'Enforces the use of `as Type` assertions instead of `` assertions', - extraDescription: [util.tslintRule('no-angle-bracket-type-assertion')], + tslintRuleName: 'no-angle-bracket-type-assertion', category: 'Stylistic Issues', - url: util.metaDocsUrl('no-angle-bracket-type-assertion'), recommended: 'error' }, messages: { @@ -31,13 +23,9 @@ const rule: RuleModule = { }, schema: [] }, - + defaultOptions: [], create(context) { const sourceCode = context.getSourceCode(); - - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- return { TSTypeAssertion(node: TSESTree.TSTypeAssertion) { context.report({ @@ -50,6 +38,4 @@ const rule: RuleModule = { } }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/no-array-constructor.ts b/packages/eslint-plugin/src/rules/no-array-constructor.ts index 548b91a606e9..c36c1ba21f3f 100644 --- a/packages/eslint-plugin/src/rules/no-array-constructor.ts +++ b/packages/eslint-plugin/src/rules/no-array-constructor.ts @@ -4,23 +4,16 @@ * @author Matt DuVall */ -import RuleModule from 'ts-eslint'; -import * as util from '../util'; import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; +import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ -type Options = []; -type MessageIds = 'useLiteral'; - -const rule: RuleModule = { +export default util.createRule({ + name: 'no-array-constructor', meta: { type: 'suggestion', docs: { description: 'Disallow generic `Array` constructors', category: 'Stylistic Issues', - url: util.metaDocsUrl('no-array-constructor'), recommended: 'error' }, fixable: 'code', @@ -29,7 +22,7 @@ const rule: RuleModule = { }, schema: [] }, - + defaultOptions: [], create(context) { /** * Disallow construction of dense arrays using the Array constructor @@ -68,6 +61,4 @@ const rule: RuleModule = { NewExpression: check }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/no-empty-interface.ts b/packages/eslint-plugin/src/rules/no-empty-interface.ts index f6fcdbacd89c..52e1d0ddf9ab 100644 --- a/packages/eslint-plugin/src/rules/no-empty-interface.ts +++ b/packages/eslint-plugin/src/rules/no-empty-interface.ts @@ -4,24 +4,16 @@ */ import { TSESTree } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -type Options = []; -type MessageIds = 'noEmpty' | 'noEmptyWithSuper'; - -const rule: RuleModule = { +export default util.createRule({ + name: 'no-empty-interface', meta: { type: 'suggestion', docs: { description: 'Disallow the declaration of empty interfaces', - extraDescription: [util.tslintRule('no-empty-interface')], + tslintRuleName: 'no-empty-interface', category: 'Best Practices', - url: util.metaDocsUrl('no-empty-interface'), recommended: 'error' }, messages: { @@ -31,34 +23,26 @@ const rule: RuleModule = { }, schema: [] }, - - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- - + defaultOptions: [], create(context) { return { TSInterfaceDeclaration(node: TSESTree.TSInterfaceDeclaration) { if (node.body.body.length !== 0) { return; } - let messageId: MessageIds | null = null; + if (!node.extends || node.extends.length === 0) { - messageId = 'noEmpty'; + context.report({ + node: node.id, + messageId: 'noEmpty' + }); } else if (node.extends.length === 1) { - messageId = 'noEmptyWithSuper'; - } - if (!messageId) { - return; + context.report({ + node: node.id, + messageId: 'noEmptyWithSuper' + }); } - - context.report({ - node: node.id, - messageId - }); } }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/no-explicit-any.ts b/packages/eslint-plugin/src/rules/no-explicit-any.ts index 6897f5e9ea6f..48a296bd25fe 100644 --- a/packages/eslint-plugin/src/rules/no-explicit-any.ts +++ b/packages/eslint-plugin/src/rules/no-explicit-any.ts @@ -4,24 +4,16 @@ * @author Patricio Trevino */ -import RuleModule from 'ts-eslint'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -type Options = []; -type MessageIds = 'unexpectedAny'; - -const rule: RuleModule = { +export default util.createRule({ + name: 'no-explicit-any', meta: { type: 'suggestion', docs: { description: 'Disallow usage of the `any` type', - extraDescription: [util.tslintRule('no-any')], + tslintRuleName: 'no-any', category: 'Best Practices', - url: util.metaDocsUrl('no-explicit-any'), recommended: 'warn' }, messages: { @@ -29,7 +21,7 @@ const rule: RuleModule = { }, schema: [] }, - + defaultOptions: [], create(context) { return { TSAnyKeyword(node) { @@ -40,6 +32,4 @@ const rule: RuleModule = { } }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/no-extraneous-class.ts b/packages/eslint-plugin/src/rules/no-extraneous-class.ts index d956e2721e76..2b3aa0a54ee2 100644 --- a/packages/eslint-plugin/src/rules/no-extraneous-class.ts +++ b/packages/eslint-plugin/src/rules/no-extraneous-class.ts @@ -4,13 +4,8 @@ */ import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - type Options = [ { allowConstructorOnly?: boolean; @@ -20,22 +15,14 @@ type Options = [ ]; type MessageIds = 'empty' | 'onlyStatic' | 'onlyConstructor'; -const defaultOptions: Options = [ - { - allowConstructorOnly: false, - allowEmpty: false, - allowStaticOnly: false - } -]; - -const rule: RuleModule = { +export default util.createRule({ + name: 'no-extraneous-class', meta: { type: 'suggestion', docs: { description: 'Forbids the use of classes as namespaces', - extraDescription: [util.tslintRule('no-unnecessary-class')], + tslintRuleName: 'no-unnecessary-class', category: 'Best Practices', - url: util.metaDocsUrl('no-extraneous-class'), recommended: false }, schema: [ @@ -61,14 +48,14 @@ const rule: RuleModule = { onlyConstructor: 'Unexpected class with only a constructor.' } }, - - create(context) { - const { - allowConstructorOnly, - allowEmpty, - allowStaticOnly - } = util.applyDefault(defaultOptions, context.options)[0]; - + defaultOptions: [ + { + allowConstructorOnly: false, + allowEmpty: false, + allowStaticOnly: false + } + ], + create(context, [{ allowConstructorOnly, allowEmpty, allowStaticOnly }]) { function getReportNode(node: TSESTree.ClassBody): TSESTree.Node { if (!node.parent) { return node; @@ -146,6 +133,4 @@ const rule: RuleModule = { } }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/no-inferrable-types.ts b/packages/eslint-plugin/src/rules/no-inferrable-types.ts index d03c7250ec19..172335302886 100644 --- a/packages/eslint-plugin/src/rules/no-inferrable-types.ts +++ b/packages/eslint-plugin/src/rules/no-inferrable-types.ts @@ -4,13 +4,8 @@ */ import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - type Options = [ { ignoreParameters?: boolean; @@ -19,22 +14,15 @@ type Options = [ ]; type MessageIds = 'noInferrableType'; -const defaultOptions: Options = [ - { - ignoreParameters: true, - ignoreProperties: true - } -]; - -const rule: RuleModule = { +export default util.createRule({ + name: 'no-inferrable-types', meta: { type: 'suggestion', docs: { description: 'Disallows explicit type declarations for variables or parameters initialized to a number, string, or boolean.', - extraDescription: [util.tslintRule('no-inferrable-types')], + tslintRuleName: 'no-inferrable-types', category: 'Best Practices', - url: util.metaDocsUrl('no-inferrable-types'), recommended: 'error' }, fixable: 'code', @@ -57,13 +45,13 @@ const rule: RuleModule = { } ] }, - - create(context) { - const { ignoreParameters, ignoreProperties } = util.applyDefault( - defaultOptions, - context.options - )[0]; - + defaultOptions: [ + { + ignoreParameters: true, + ignoreProperties: true + } + ], + create(context, [{ ignoreParameters, ignoreProperties }]) { /** * Returns whether a node has an inferrable value or not * @param node the node to check @@ -212,6 +200,4 @@ const rule: RuleModule = { ClassProperty: inferrablePropertyVisitor }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/no-misused-new.ts b/packages/eslint-plugin/src/rules/no-misused-new.ts index ad366a7b009d..dfd4c012f1fd 100644 --- a/packages/eslint-plugin/src/rules/no-misused-new.ts +++ b/packages/eslint-plugin/src/rules/no-misused-new.ts @@ -4,24 +4,16 @@ */ import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -type Options = []; -type MessageIds = 'errorMessageInterface' | 'errorMessageClass'; - -const rule: RuleModule = { +export default util.createRule({ + name: 'no-misused-new', meta: { type: 'problem', docs: { description: 'Enforce valid definition of `new` and `constructor`.', - extraDescription: [util.tslintRule('no-misused-new')], + tslintRuleName: 'no-misused-new', category: 'Best Practices', - url: util.metaDocsUrl('no-misused-new'), recommended: 'error' }, schema: [], @@ -30,11 +22,7 @@ const rule: RuleModule = { errorMessageClass: 'Class cannon have method named `new`.' } }, - - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- - + defaultOptions: [], create(context) { /** * @param {ASTNode} node type to be inspected. @@ -123,6 +111,4 @@ const rule: RuleModule = { } }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/no-namespace.ts b/packages/eslint-plugin/src/rules/no-namespace.ts index 3d0229f69766..8e48d7220929 100644 --- a/packages/eslint-plugin/src/rules/no-namespace.ts +++ b/packages/eslint-plugin/src/rules/no-namespace.ts @@ -4,13 +4,8 @@ */ import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - type Options = [ { allowDeclarations?: boolean; @@ -19,22 +14,15 @@ type Options = [ ]; type MessageIds = 'moduleSyntaxIsPreferred'; -const defaultOptions: Options = [ - { - allowDeclarations: false, - allowDefinitionFiles: true - } -]; - -const rule: RuleModule = { +export default util.createRule({ + name: 'no-namespace', meta: { type: 'suggestion', docs: { description: 'Disallow the use of custom TypeScript modules and namespaces', - extraDescription: [util.tslintRule('no-namespace')], + tslintRuleName: 'no-namespace', category: 'Best Practices', - url: util.metaDocsUrl('no-namespace'), recommended: 'error' }, messages: { @@ -56,17 +44,15 @@ const rule: RuleModule = { } ] }, - - create(context) { - const { allowDeclarations, allowDefinitionFiles } = util.applyDefault( - defaultOptions, - context.options - )[0]; + defaultOptions: [ + { + allowDeclarations: false, + allowDefinitionFiles: true + } + ], + create(context, [{ allowDeclarations, allowDefinitionFiles }]) { const filename = context.getFilename(); - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- return { "TSModuleDeclaration[global!=true][id.type='Identifier']"( node: TSESTree.TSModuleDeclaration @@ -87,6 +73,4 @@ const rule: RuleModule = { } }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/no-non-null-assertion.ts b/packages/eslint-plugin/src/rules/no-non-null-assertion.ts index 334a140a92b1..3abe06f71a25 100644 --- a/packages/eslint-plugin/src/rules/no-non-null-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-non-null-assertion.ts @@ -4,25 +4,17 @@ */ import { TSESTree } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -type Options = []; -type MessageIds = 'noNonNull'; - -const rule: RuleModule = { +export default util.createRule({ + name: 'no-non-null-assertion', meta: { type: 'problem', docs: { description: 'Disallows non-null assertions using the `!` postfix operator', - extraDescription: [util.tslintRule('no-non-null-assertion')], + tslintRuleName: 'no-non-null-assertion', category: 'Stylistic Issues', - url: util.metaDocsUrl('no-non-null-assertion'), recommended: 'error' }, messages: { @@ -30,11 +22,8 @@ const rule: RuleModule = { }, schema: [] }, + defaultOptions: [], create(context) { - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- - return { TSNonNullExpression(node: TSESTree.TSNonNullExpression) { context.report({ @@ -44,6 +33,4 @@ const rule: RuleModule = { } }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts b/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts index cd6efdd91d07..260bf47d95d3 100644 --- a/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-object-literal-type-assertion.ts @@ -4,13 +4,8 @@ */ import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - type Options = [ { allowAsParameter?: boolean; @@ -18,21 +13,15 @@ type Options = [ ]; type MessageIds = 'unexpectedTypeAssertion'; -const defaultOptions: Options = [ - { - allowAsParameter: false - } -]; - -const rule: RuleModule = { +export default util.createRule({ + name: 'no-object-literal-type-assertions', meta: { type: 'problem', docs: { description: 'Forbids an object literal to appear in a type assertion expression', - extraDescription: [util.tslintRule('no-object-literal-type-assertion')], + tslintRuleName: 'no-object-literal-type-assertion', category: 'Stylistic Issues', - url: util.metaDocsUrl('no-object-literal-type-assertions'), recommended: 'error' }, messages: { @@ -51,16 +40,12 @@ const rule: RuleModule = { } ] }, - create(context) { - const { allowAsParameter } = util.applyDefault( - defaultOptions, - context.options - )[0]; - - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- - + defaultOptions: [ + { + allowAsParameter: false + } + ], + create(context, [{ allowAsParameter }]) { /** * Check whatever node should be reported * @param node the node to be evaluated. @@ -100,5 +85,4 @@ const rule: RuleModule = { } }; } -}; -export default rule; +}); diff --git a/packages/eslint-plugin/src/rules/no-parameter-properties.ts b/packages/eslint-plugin/src/rules/no-parameter-properties.ts index e9ce3d4638af..cce3af7b3620 100644 --- a/packages/eslint-plugin/src/rules/no-parameter-properties.ts +++ b/packages/eslint-plugin/src/rules/no-parameter-properties.ts @@ -4,13 +4,8 @@ */ import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - type Modifier = | 'readonly' | 'private' @@ -26,21 +21,15 @@ type Options = [ ]; type MessageIds = 'noParamProp'; -const defaultOptions: Options = [ - { - allows: [] - } -]; - -const rule: RuleModule = { +export default util.createRule({ + name: 'no-parameter-properties', meta: { type: 'problem', docs: { description: 'Disallow the use of parameter properties in class constructors.', - extraDescription: [util.tslintRule('no-parameter-properties')], + tslintRuleName: 'no-parameter-properties', category: 'Stylistic Issues', - url: util.metaDocsUrl('no-parameter-properties'), recommended: 'error' }, messages: { @@ -71,14 +60,12 @@ const rule: RuleModule = { } ] }, - - create(context) { - const { allows } = util.applyDefault(defaultOptions, context.options)[0]; - - //---------------------------------------------------------------------- - // Helpers - //---------------------------------------------------------------------- - + defaultOptions: [ + { + allows: [] + } + ], + create(context, [{ allows }]) { /** * Gets the modifiers of `node`. * @param node the node to be inspected. @@ -96,9 +83,6 @@ const rule: RuleModule = { return modifiers.filter(Boolean).join(' ') as Modifier; } - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- return { TSParameterProperty(node: TSESTree.TSParameterProperty) { const modifiers = getModifiers(node); @@ -129,5 +113,4 @@ const rule: RuleModule = { } }; } -}; -export default rule; +}); diff --git a/packages/eslint-plugin/src/rules/no-this-alias.ts b/packages/eslint-plugin/src/rules/no-this-alias.ts index bb6419d8bb85..6f0c34add032 100644 --- a/packages/eslint-plugin/src/rules/no-this-alias.ts +++ b/packages/eslint-plugin/src/rules/no-this-alias.ts @@ -4,13 +4,8 @@ */ import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - type Options = [ { allowDestructuring?: boolean; @@ -19,21 +14,14 @@ type Options = [ ]; type MessageIds = 'thisAssignment' | 'thisDestructure'; -const defaultOptions: Options = [ - { - allowDestructuring: false, - allowedNames: [] as string[] - } -]; - -const rule: RuleModule = { +export default util.createRule({ + name: 'no-this-alias', meta: { type: 'suggestion', docs: { description: 'Disallow aliasing `this`', - extraDescription: [util.tslintRule('no-this-assignment')], + tslintRuleName: 'no-this-assignment', category: 'Best Practices', - url: util.metaDocsUrl('no-this-alias'), recommended: false }, schema: [ @@ -59,13 +47,13 @@ const rule: RuleModule = { "Unexpected aliasing of members of 'this' to local variables." } }, - - create(context) { - const { allowDestructuring, allowedNames } = util.applyDefault( - defaultOptions, - context.options - )[0]; - + defaultOptions: [ + { + allowDestructuring: false, + allowedNames: [] + } + ], + create(context, [{ allowDestructuring, allowedNames }]) { return { "VariableDeclarator[init.type='ThisExpression']"( node: TSESTree.VariableDeclarator @@ -92,6 +80,4 @@ const rule: RuleModule = { } }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts b/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts index c6fbc469294a..9691edb201ed 100644 --- a/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts +++ b/packages/eslint-plugin/src/rules/no-triple-slash-reference.ts @@ -3,25 +3,17 @@ * @author Danny Fritz */ -import RuleModule from 'ts-eslint'; -import * as util from '../util'; import { TSESTree } from '@typescript-eslint/typescript-estree'; +import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -type Options = []; -type MessageIds = 'tripleSlashReference'; - -const rule: RuleModule = { +export default util.createRule({ + name: 'no-triple-slash-reference', meta: { type: 'suggestion', docs: { description: 'Disallow `/// ` comments', - extraDescription: [util.tslintRule('no-reference')], + tslintRuleName: 'no-reference', category: 'Best Practices', - url: util.metaDocsUrl('no-triple-slash-reference'), recommended: 'error' }, schema: [], @@ -29,18 +21,11 @@ const rule: RuleModule = { tripleSlashReference: 'Do not use a triple slash reference.' } }, - + defaultOptions: [], create(context) { const referenceRegExp = /^\/\s* = { } }; } -}; -export default rule; +}); diff --git a/packages/eslint-plugin/src/rules/no-type-alias.ts b/packages/eslint-plugin/src/rules/no-type-alias.ts index 1f7d73cbee74..41ebcaa0aa4e 100644 --- a/packages/eslint-plugin/src/rules/no-type-alias.ts +++ b/packages/eslint-plugin/src/rules/no-type-alias.ts @@ -4,13 +4,9 @@ */ import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/typescript-estree'; -import RuleModule, { ReportDescriptor } from 'ts-eslint'; +import { ReportDescriptor } from 'ts-eslint'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - type Options = [ { allowAliases?: @@ -36,23 +32,14 @@ type Options = [ ]; type MessageIds = 'noTypeAlias' | 'noCompositionAlias'; -const defaultOptions: Options = [ - { - allowAliases: 'never', - allowCallbacks: 'never', - allowLiterals: 'never', - allowMappedTypes: 'never' - } -]; - -const rule: RuleModule = { +export default util.createRule({ + name: 'no-type-alias', meta: { type: 'suggestion', docs: { description: 'Disallow the use of type aliases', - extraDescription: [util.tslintRule('interface-over-type-literal')], + tslintRuleName: 'interface-over-type-literal', category: 'Stylistic Issues', - url: util.metaDocsUrl('no-type-alias'), recommended: false }, messages: { @@ -99,15 +86,18 @@ const rule: RuleModule = { } ] }, - - create(context) { - const { - allowAliases, - allowCallbacks, - allowLiterals, - allowMappedTypes - } = util.applyDefault(defaultOptions, context.options)[0]; - + defaultOptions: [ + { + allowAliases: 'never', + allowCallbacks: 'never', + allowLiterals: 'never', + allowMappedTypes: 'never' + } + ], + create( + context, + [{ allowAliases, allowCallbacks, allowLiterals, allowMappedTypes }] + ) { const unions = ['always', 'in-unions', 'in-unions-and-intersections']; const intersections = [ 'always', @@ -121,10 +111,6 @@ const rule: RuleModule = { ]; const aliasTypes = ['TSArrayType', 'TSTypeReference', 'TSLiteralType']; - //---------------------------------------------------------------------- - // Helpers - //---------------------------------------------------------------------- - type CompositionType = TSESTree.TSUnionType | TSESTree.TSIntersectionType; /** * Determines if the given node is a union or an intersection. @@ -299,9 +285,6 @@ const rule: RuleModule = { }); } - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- return { TSTypeAliasDeclaration(node: TSESTree.TSTypeAliasDeclaration) { if (isComposition(node.typeAnnotation)) { @@ -312,5 +295,4 @@ const rule: RuleModule = { } }; } -}; -export default rule; +}); diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts b/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts index e218831c888c..f0138389e39a 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts @@ -4,15 +4,10 @@ */ import { TSESTree } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import * as tsutils from 'tsutils'; import ts from 'typescript'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - type Options = [ { typesToIgnore?: string[]; @@ -20,15 +15,15 @@ type Options = [ ]; type MessageIds = 'unnecessaryAssertion'; -const rule: RuleModule = { +export default util.createRule({ + name: 'no-unnecessary-type-assertion', meta: { docs: { description: 'Warns if a type assertion does not change the type of an expression', category: 'Best Practices', recommended: false, - extraDescription: [util.tslintRule('no-unnecessary-type-assertion')], - url: util.metaDocsUrl('no-unnecessary-type-assertion') + tslintRuleName: 'no-unnecessary-type-assertion' }, fixable: 'code', messages: { @@ -50,8 +45,8 @@ const rule: RuleModule = { ], type: 'suggestion' }, - - create(context) { + defaultOptions: [{}], + create(context, [options]) { const parserServices = util.getParserServices(context); /** @@ -125,10 +120,7 @@ const rule: RuleModule = { const originalNode = parserServices.esTreeNodeToTSNodeMap.get< ts.AssertionExpression >(node); - const options = context.options[0]; - if ( - options && options.typesToIgnore && options.typesToIgnore.indexOf(originalNode.type.getText()) !== -1 ) { @@ -182,6 +174,4 @@ const rule: RuleModule = { } }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/no-unused-vars.ts b/packages/eslint-plugin/src/rules/no-unused-vars.ts index 5c0a10a8e4e2..2d63aa4564f8 100644 --- a/packages/eslint-plugin/src/rules/no-unused-vars.ts +++ b/packages/eslint-plugin/src/rules/no-unused-vars.ts @@ -4,31 +4,23 @@ */ import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import baseRule from 'eslint/lib/rules/no-unused-vars'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -type Options = util.InferOptionsTypeFromRule; -type MessageIds = util.InferMessageIdsTypeFromRule; - -const rule: RuleModule = { +export default util.createRule({ + name: 'no-unused-vars', meta: { type: 'problem', docs: { description: 'Disallow unused variables', - extraDescription: [util.tslintRule('no-unused-variable')], + tslintRuleName: 'no-unused-variable', category: 'Variables', - url: util.metaDocsUrl('no-unused-vars'), recommended: 'warn' }, schema: baseRule.meta.schema, messages: baseRule.meta.messages }, - + defaultOptions: [], create(context) { const rules = baseRule.create(context); @@ -66,9 +58,6 @@ const rule: RuleModule = { } } - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- return Object.assign({}, rules, { "FunctionDeclaration Identifier[name='this']": markThisParameterAsUsed, "FunctionExpression Identifier[name='this']": markThisParameterAsUsed, @@ -105,6 +94,4 @@ const rule: RuleModule = { } }); } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/no-use-before-define.ts b/packages/eslint-plugin/src/rules/no-use-before-define.ts index 82ccc76721e7..6aff11933bf0 100644 --- a/packages/eslint-plugin/src/rules/no-use-before-define.ts +++ b/packages/eslint-plugin/src/rules/no-use-before-define.ts @@ -5,13 +5,9 @@ */ import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/typescript-estree'; -import RuleModule, { Scope } from 'ts-eslint'; +import { Scope } from 'ts-eslint'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - const SENTINEL_TYPE = /^(?:(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|CatchClause|ImportDeclaration|ExportNamedDeclaration)$/; /** @@ -151,10 +147,6 @@ function isInInitializer( return false; } -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - interface Config { functions?: boolean; classes?: boolean; @@ -164,22 +156,13 @@ interface Config { type Options = ['nofunc' | Config]; type MessageIds = 'noUseBeforeDefine'; -const defaultOptions: Options = [ - { - functions: true, - classes: true, - variables: true, - typedefs: true - } -]; - -const rule: RuleModule = { +export default util.createRule({ + name: 'no-use-before-define', meta: { type: 'problem', docs: { description: 'Disallow the use of variables before they are defined', category: 'Variables', - url: util.metaDocsUrl('no-use-before-define'), recommended: 'error' }, messages: { @@ -205,11 +188,16 @@ const rule: RuleModule = { } ] }, - - create(context) { - const options = parseOptions( - util.applyDefault(defaultOptions, context.options)[0] - ); + defaultOptions: [ + { + functions: true, + classes: true, + variables: true, + typedefs: true + } + ], + create(context, optionsWithDefault) { + const options = parseOptions(optionsWithDefault[0]); /** * Determines whether a given use-before-define case should be reported according to the options. @@ -273,6 +261,4 @@ const rule: RuleModule = { } }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/no-useless-constructor.ts b/packages/eslint-plugin/src/rules/no-useless-constructor.ts index d5ba1f5a8f13..944ad6ff0c68 100644 --- a/packages/eslint-plugin/src/rules/no-useless-constructor.ts +++ b/packages/eslint-plugin/src/rules/no-useless-constructor.ts @@ -4,13 +4,9 @@ */ import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import baseRule from 'eslint/lib/rules/no-useless-constructor'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ type Options = util.InferOptionsTypeFromRule; type MessageIds = util.InferMessageIdsTypeFromRule; @@ -49,25 +45,21 @@ function checkParams(node: TSESTree.MethodDefinition): boolean { ); } -const rule: RuleModule = { +export default util.createRule({ + name: 'no-useless-constructor', meta: { type: 'problem', docs: { description: 'Disallow unnecessary constructors', category: 'Best Practices', - recommended: false, - url: util.metaDocsUrl('no-useless-constructor') + recommended: false }, schema: baseRule.meta.schema, messages: baseRule.meta.messages }, - + defaultOptions: [], create(context) { const rules = baseRule.create(context); - - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- return { MethodDefinition(node: TSESTree.MethodDefinition) { if ( @@ -81,6 +73,4 @@ const rule: RuleModule = { } }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/no-var-requires.ts b/packages/eslint-plugin/src/rules/no-var-requires.ts index d935386b7eb0..243bfcd4640d 100644 --- a/packages/eslint-plugin/src/rules/no-var-requires.ts +++ b/packages/eslint-plugin/src/rules/no-var-requires.ts @@ -4,25 +4,20 @@ */ import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - type Options = []; type MessageIds = 'noVarReqs'; -const rule: RuleModule = { +export default util.createRule({ + name: 'no-var-requires', meta: { type: 'problem', docs: { description: 'Disallows the use of require statements except in import statements', - extraDescription: [util.tslintRule('no-var-requires')], + tslintRuleName: 'no-var-requires', category: 'Best Practices', - url: util.metaDocsUrl('no-var-requires'), recommended: 'error' }, messages: { @@ -30,11 +25,8 @@ const rule: RuleModule = { }, schema: [] }, + defaultOptions: [], create(context) { - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- - return { CallExpression(node: TSESTree.CallExpression) { if ( @@ -51,6 +43,4 @@ const rule: RuleModule = { } }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/rules/prefer-interface.ts b/packages/eslint-plugin/src/rules/prefer-interface.ts index c48e8648c500..b9421e159530 100644 --- a/packages/eslint-plugin/src/rules/prefer-interface.ts +++ b/packages/eslint-plugin/src/rules/prefer-interface.ts @@ -4,25 +4,18 @@ */ import { TSESTree } from '@typescript-eslint/typescript-estree'; -import RuleModule, { RuleFix } from 'ts-eslint'; +import { RuleFix } from 'ts-eslint'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -type Options = []; -type MessageIds = 'interfaceOverType'; - -const rule: RuleModule = { +export default util.createRule({ + name: 'prefer-interface', meta: { type: 'suggestion', docs: { description: 'Prefer an interface declaration over a type literal (type T = { ... })', - extraDescription: [util.tslintRule('interface-over-type-literal')], + tslintRuleName: 'interface-over-type-literal', category: 'Stylistic Issues', - url: util.metaDocsUrl('prefer-interface'), recommended: 'error' }, fixable: 'code', @@ -31,12 +24,10 @@ const rule: RuleModule = { }, schema: [] }, + defaultOptions: [], create(context) { const sourceCode = context.getSourceCode(); - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- return { // VariableDeclaration with kind type has only one VariableDeclarator "TSTypeAliasDeclaration[typeAnnotation.type='TSTypeLiteral']"( @@ -75,5 +66,4 @@ const rule: RuleModule = { } }; } -}; -export default rule; +}); diff --git a/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts b/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts index cbed97e936a1..1ab088fa1121 100644 --- a/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts +++ b/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts @@ -5,25 +5,17 @@ */ import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/typescript-estree'; -import RuleModule from 'ts-eslint'; import * as util from '../util'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -type Options = []; -type MessageIds = 'useNamespace'; - -const rule: RuleModule = { +export default util.createRule({ + name: 'prefer-namespace-keyword', meta: { type: 'suggestion', docs: { description: 'Require the use of the `namespace` keyword instead of the `module` keyword to declare custom TypeScript modules.', - extraDescription: [util.tslintRule('no-internal-module')], + tslintRuleName: 'no-internal-module', category: 'Best Practices', - url: util.metaDocsUrl('prefer-namespace-keyword'), recommended: 'error' }, fixable: 'code', @@ -33,13 +25,10 @@ const rule: RuleModule = { }, schema: [] }, - + defaultOptions: [], create(context) { const sourceCode = context.getSourceCode(); - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- return { TSModuleDeclaration(node: TSESTree.TSModuleDeclaration) { // Do nothing if the name is a string. @@ -65,5 +54,4 @@ const rule: RuleModule = { } }; } -}; -export default rule; +}); diff --git a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts index 24d037b0819b..f0e5696a5595 100644 --- a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts +++ b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts @@ -4,28 +4,20 @@ * @author Armano */ -import RuleModule from 'ts-eslint'; +import { TSESTree } from '@typescript-eslint/typescript-estree'; import ts from 'typescript'; import * as util from '../util'; -import { TSESTree } from '@typescript-eslint/typescript-estree'; - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ -type Options = []; -type MessageIds = 'notNumbers' | 'notStrings'; - -const rule: RuleModule = { +export default util.createRule({ + name: 'restrict-plus-operands', meta: { type: 'problem', docs: { description: 'When adding two variables, operands must both be of type number or of type string.', - extraDescription: [util.tslintRule('restrict-plus-operands')], + tslintRuleName: 'restrict-plus-operands', category: 'Best Practices', - recommended: false, - url: util.metaDocsUrl('restrict-plus-operands') + recommended: false }, messages: { notNumbers: @@ -35,7 +27,7 @@ const rule: RuleModule = { }, schema: [] }, - + defaultOptions: [], create(context) { const service = util.getParserServices(context); @@ -80,9 +72,6 @@ const rule: RuleModule = { return getBaseTypeOfLiteralType(type); } - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- return { "BinaryExpression[operator='+']"(node: TSESTree.BinaryExpression) { const leftType = getNodeType(node.left); @@ -108,5 +97,4 @@ const rule: RuleModule = { } }; } -}; -export default rule; +}); diff --git a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts index 92f39a86baa1..391f6523095f 100644 --- a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts +++ b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts @@ -4,14 +4,9 @@ * @author Patricio Trevino */ -import RuleModule from 'ts-eslint'; import * as util from '../util'; import { TSESTree } from '@typescript-eslint/typescript-estree'; -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - type Options = [ { before?: boolean; @@ -43,20 +38,14 @@ const definition = { additionalProperties: false }; -const defaultOptions: Options = [ - // technically there is a default, but the overrides mean - // that if we apply them here, it will break the no override case. - {} -]; - -const rule: RuleModule = { +export default util.createRule({ + name: 'type-annotation-spacing', meta: { type: 'layout', docs: { description: 'Require consistent spacing around type annotations', - extraDescription: [util.tslintRule('typedef-whitespace')], + tslintRuleName: 'typedef-whitespace', category: 'Stylistic Issues', - url: util.metaDocsUrl('type-annotation-spacing'), recommended: 'error' }, fixable: 'whitespace', @@ -85,11 +74,14 @@ const rule: RuleModule = { } ] }, - - create(context) { + defaultOptions: [ + // technically there is a default, but the overrides mean + // that if we apply them here, it will break the no override case. + {} + ], + create(context, [options]) { const punctuators = [':', '=>']; const sourceCode = context.getSourceCode(); - const options = util.applyDefault(defaultOptions, context.options)[0]; const overrides = options!.overrides || { colon: {}, arrow: {} }; @@ -106,10 +98,6 @@ const rule: RuleModule = { overrides.arrow ); - //---------------------------------------------------------------------- - // Helpers - //---------------------------------------------------------------------- - /** * Checks if there's proper spacing around type annotations (no space * before colon, one space after). @@ -203,9 +191,6 @@ const rule: RuleModule = { } } - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- return { TSMappedType(node: TSESTree.TSMappedType) { if (node.typeAnnotation) { @@ -217,6 +202,4 @@ const rule: RuleModule = { } }; } -}; -export default rule; -export { Options, MessageIds }; +}); diff --git a/packages/eslint-plugin/src/util/createRule.ts b/packages/eslint-plugin/src/util/createRule.ts new file mode 100644 index 000000000000..4b7268cf7adf --- /dev/null +++ b/packages/eslint-plugin/src/util/createRule.ts @@ -0,0 +1,61 @@ +import RuleModule, { + RuleListener, + RuleMetaData, + RuleMetaDataDocs, + RuleContext +} from 'ts-eslint'; +import { applyDefault } from './applyDefault'; + +// note - cannot migrate this to an import statement because it will make TSC copy the package.json to the dist folder +const version = require('../../package.json').version; + +// Utility type to remove a list of properties from an object +type RemoveProps< + TObj extends Record, + TKeys extends keyof TObj +> = Pick>; + +// we'll automatically +type CreateRuleMetaDocs = RemoveProps & { + tslintName?: string; +}; +type CreateRuleMeta = { + docs: CreateRuleMetaDocs; +} & RemoveProps, 'docs'>; + +// This function will get much easier to call when this is merged https://github.com/Microsoft/TypeScript/pull/26349 +export function createRule< + TOptions extends Readonly, + TMessageIds extends string, + TRuleListener extends RuleListener = RuleListener +>({ + name, + meta, + defaultOptions, + create +}: { + name: string; + meta: CreateRuleMeta; + defaultOptions: TOptions; + create: ( + context: RuleContext, + optionsWithDefault: TOptions + ) => TRuleListener; +}): RuleModule { + return { + meta: { + ...meta, + docs: { + ...meta.docs, + url: `https://github.com/typescript-eslint/typescript-eslint/blob/${version}/packages/eslint-plugin/docs/rules/${name}.md`, + extraDescription: meta.docs.tslintName + ? [`\`${meta.docs.tslintName}\` from TSLint`] + : undefined + } + }, + create(context) { + const optionsWithDefault = applyDefault(defaultOptions, context.options); + return create(context, optionsWithDefault); + } + }; +} diff --git a/packages/eslint-plugin/tests/RuleTester.ts b/packages/eslint-plugin/tests/RuleTester.ts index 37a4867fb75b..0acd41a3b138 100644 --- a/packages/eslint-plugin/tests/RuleTester.ts +++ b/packages/eslint-plugin/tests/RuleTester.ts @@ -3,7 +3,7 @@ import { RuleTester } from 'eslint'; import RuleModule from 'ts-eslint'; import { ParserOptions } from '@typescript-eslint/parser'; -interface ValidTestCase { +interface ValidTestCase> { code: string; options?: TOptions; filename?: string; @@ -13,8 +13,10 @@ interface ValidTestCase { globals?: Record; } -interface InvalidTestCase - extends ValidTestCase { +interface InvalidTestCase< + TMessageIds extends string, + TOptions extends Readonly +> extends ValidTestCase { errors: TestCaseError[]; output?: string; } @@ -29,14 +31,17 @@ interface TestCaseError { // endColumn?: number; } -interface RunTests { +interface RunTests< + TMessageIds extends string, + TOptions extends Readonly +> { // RuleTester.run also accepts strings for valid cases valid: (ValidTestCase | string)[]; invalid: InvalidTestCase[]; } declare class RuleTesterTyped { - run( + run>( name: string, rule: RuleModule, tests: RunTests diff --git a/packages/eslint-plugin/tests/rules/ban-types.test.ts b/packages/eslint-plugin/tests/rules/ban-types.test.ts index 1fb9946241d9..2aafd3334eaf 100644 --- a/packages/eslint-plugin/tests/rules/ban-types.test.ts +++ b/packages/eslint-plugin/tests/rules/ban-types.test.ts @@ -7,8 +7,9 @@ // Requirements //------------------------------------------------------------------------------ -import rule, { Options } from '../../src/rules/ban-types'; +import rule from '../../src/rules/ban-types'; import RuleTester from '../RuleTester'; +import { InferOptionsTypeFromRule } from '../../src/util'; //------------------------------------------------------------------------------ // Tests @@ -18,7 +19,7 @@ const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); -const options: Options = [ +const options: InferOptionsTypeFromRule = [ { types: { String: { diff --git a/packages/eslint-plugin/tests/rules/indent.test.ts b/packages/eslint-plugin/tests/rules/indent.test.ts index 57f3907374d2..fcf035426fee 100644 --- a/packages/eslint-plugin/tests/rules/indent.test.ts +++ b/packages/eslint-plugin/tests/rules/indent.test.ts @@ -8,8 +8,15 @@ // Requirements //------------------------------------------------------------------------------ -import rule, { Options, MessageIds } from '../../src/rules/indent'; +import rule from '../../src/rules/indent'; import RuleTester, { RunTests, TestCaseError } from '../RuleTester'; +import { + InferMessageIdsTypeFromRule, + InferOptionsTypeFromRule +} from '../../src/util'; + +type MessageIds = InferMessageIdsTypeFromRule; +type Options = InferOptionsTypeFromRule; /** * Marks a test case as a plain javascript case which should be indented the same diff --git a/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts index 07ae28a379d0..dbd5b034f248 100644 --- a/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts @@ -7,11 +7,15 @@ // Requirements //------------------------------------------------------------------------------ -import rule, { - Options, - MessageIds -} from '../../src/rules/type-annotation-spacing'; +import rule from '../../src/rules/type-annotation-spacing'; import RuleTester, { InvalidTestCase, ValidTestCase } from '../RuleTester'; +import { + InferMessageIdsTypeFromRule, + InferOptionsTypeFromRule +} from '../../src/util'; + +type MessageIds = InferMessageIdsTypeFromRule; +type Options = InferOptionsTypeFromRule; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/typings/ts-eslint.d.ts b/packages/eslint-plugin/typings/ts-eslint.d.ts index 542fa8f48334..68dd91e365f9 100644 --- a/packages/eslint-plugin/typings/ts-eslint.d.ts +++ b/packages/eslint-plugin/typings/ts-eslint.d.ts @@ -202,6 +202,30 @@ declare module 'ts-eslint' { //#region Rule + interface RuleMetaDataDocs { + /** + * The general category the rule falls within + */ + category: 'Best Practices' | 'Stylistic Issues' | 'Variables'; + /** + * Concise description of the rule + */ + description: string; + /** + * Extra information linking the rule to a tslint rule + */ + extraDescription?: string[]; + /** + * The recommendation level for the rule. + * Used by the build tools to generate the recommended config. + * Set to false to not include it as a recommendation + */ + recommended: 'error' | 'warn' | false; + /** + * The URL of the rule's docs + */ + url: string; + } interface RuleMetaData { /** * True if the rule is deprecated, false otherwise @@ -210,30 +234,7 @@ declare module 'ts-eslint' { /** * Documentation for the rule */ - docs: { - /** - * The general category the rule falls within - */ - category: 'Best Practices' | 'Stylistic Issues' | 'Variables'; - /** - * Concise description of the rule - */ - description: string; - /** - * Extra information linking the rule to a tslint rule - */ - extraDescription?: string[]; - /** - * The recommendation level for the rule. - * Used by the build tools to generate the recommended config. - * Set to false to not include it as a recommendation - */ - recommended: 'error' | 'warn' | false; - /** - * The URL of the rule's docs - */ - url: string; - }; + docs: RuleMetaDataDocs; /** * The fixer category. Omit if there is no fixer */ @@ -315,7 +316,10 @@ declare module 'ts-eslint' { loc?: TSESTree.SourceLocation; } - interface RuleContext { + interface RuleContext< + TMessageIds extends string, + TOptions extends Readonly + > { /** * The rule ID. */ @@ -391,7 +395,7 @@ declare module 'ts-eslint' { interface RuleModule< TMessageIds extends string, - TOptions extends any[], + TOptions extends Readonly, // for extending base rules TRuleListener extends RuleListener = RuleListener > { @@ -510,6 +514,15 @@ declare module 'ts-eslint' { type Definition = DefinitionType & { name: TSESTree.Identifier }; } - export { RuleContext, RuleFix, ReportFixFunction, ReportDescriptor, Scope }; + export { + ReportDescriptor, + ReportFixFunction, + RuleContext, + RuleFix, + RuleListener, + RuleMetaData, + RuleMetaDataDocs, + Scope + }; export default RuleModule; } From 265a6c1181b62e0e18a48be482a543efb39f2c2f Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Wed, 6 Feb 2019 10:56:37 -0800 Subject: [PATCH 77/92] remove a number of inconsistent/useless comments --- packages/eslint-plugin/src/index.ts | 9 --------- .../tests/eslint-rules/arrow-parens.test.ts | 6 ------ .../tests/eslint-rules/no-dupe-args.test.ts | 6 ------ .../eslint-rules/no-implicit-globals.test.ts | 6 ------ .../tests/eslint-rules/no-redeclare.test.ts | 6 ------ .../eslint-rules/no-restricted-globals.test.ts | 6 ------ .../tests/eslint-rules/no-shadow.test.ts | 6 ------ .../tests/eslint-rules/no-undef.test.ts | 10 ---------- .../tests/eslint-rules/no-unused-vars.test.ts | 6 ------ .../eslint-rules/no-use-before-define.test.ts | 6 ------ .../tests/eslint-rules/strict.test.ts | 6 ------ .../rules/adjacent-overload-signatures.test.ts | 13 ------------- .../tests/rules/array-type.test.ts | 17 +---------------- .../eslint-plugin/tests/rules/ban-types.test.ts | 13 ------------- .../eslint-plugin/tests/rules/camelcase.test.ts | 15 --------------- .../tests/rules/class-name-casing.test.ts | 14 -------------- .../rules/explicit-function-return-type.test.ts | 13 ------------- .../rules/explicit-member-accessibility.test.ts | 13 ------------- .../tests/rules/generic-type-naming.test.ts | 12 ------------ .../eslint-plugin/tests/rules/indent.test.ts | 10 ---------- .../tests/rules/interface-name-prefix.test.ts | 13 ------------- .../tests/rules/member-delimiter-style.test.ts | 14 -------------- .../tests/rules/member-naming.test.ts | 13 ------------- .../tests/rules/member-ordering.test.ts | 13 ------------- .../no-angle-bracket-type-assertion.test.ts | 13 ------------- .../tests/rules/no-array-constructor.test.ts | 14 -------------- .../tests/rules/no-empty-interface.test.ts | 13 ------------- .../tests/rules/no-explicit-any.test.ts | 13 ------------- .../tests/rules/no-extraneous-class.test.ts | 14 -------------- .../tests/rules/no-inferrable-types.test.ts | 13 ------------- .../tests/rules/no-misused-new.test.ts | 13 ------------- .../tests/rules/no-namespace.test.ts | 13 ------------- .../tests/rules/no-non-null-assertion.test.ts | 13 ------------- .../no-object-literal-type-assertion.test.ts | 13 ------------- .../tests/rules/no-parameter-properties.test.ts | 13 ------------- .../tests/rules/no-this-alias.test.ts | 14 -------------- .../rules/no-triple-slash-reference.test.ts | 13 ------------- .../tests/rules/no-type-alias.test.ts | 13 ------------- .../rules/no-unnecessary-type-assertion.test.ts | 14 -------------- .../tests/rules/no-unused-vars.test.ts | 13 ------------- .../tests/rules/no-use-before-define.test.ts | 14 -------------- .../tests/rules/no-useless-constructor.test.ts | 6 ------ .../tests/rules/no-var-requires.test.ts | 13 ------------- .../tests/rules/prefer-interface.test.ts | 13 ------------- .../rules/prefer-namespace-keyword.test.ts | 14 -------------- .../tests/rules/restrict-plus-operands.test.ts | 16 +--------------- .../tests/rules/type-annotation-spacing.test.ts | 13 ------------- 47 files changed, 2 insertions(+), 545 deletions(-) diff --git a/packages/eslint-plugin/src/index.ts b/packages/eslint-plugin/src/index.ts index 64e0a102febf..f18b90cf41e3 100644 --- a/packages/eslint-plugin/src/index.ts +++ b/packages/eslint-plugin/src/index.ts @@ -2,21 +2,12 @@ * @fileoverview TypeScript plugin for ESLint * @author Nicholas C. Zakas */ -'use strict'; - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ import requireIndex from 'requireindex'; import path from 'path'; import recommended from './configs/recommended.json'; -//------------------------------------------------------------------------------ -// Plugin Definition -//------------------------------------------------------------------------------ - const rules = requireIndex(path.join(__dirname, 'rules')); // eslint expects the rule to be on rules[name], not rules[name].default const rulesWithoutDefault = Object.keys(rules).reduce>( diff --git a/packages/eslint-plugin/tests/eslint-rules/arrow-parens.test.ts b/packages/eslint-plugin/tests/eslint-rules/arrow-parens.test.ts index 373d4f0afc68..a8992a34ccf5 100644 --- a/packages/eslint-plugin/tests/eslint-rules/arrow-parens.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/arrow-parens.test.ts @@ -1,9 +1,3 @@ -'use strict'; - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from 'eslint/lib/rules/arrow-parens'; import RuleTester from '../RuleTester'; diff --git a/packages/eslint-plugin/tests/eslint-rules/no-dupe-args.test.ts b/packages/eslint-plugin/tests/eslint-rules/no-dupe-args.test.ts index 242401442324..0c227678a877 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-dupe-args.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-dupe-args.test.ts @@ -1,9 +1,3 @@ -'use strict'; - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from 'eslint/lib/rules/no-dupe-args'; import RuleTester from '../RuleTester'; diff --git a/packages/eslint-plugin/tests/eslint-rules/no-implicit-globals.test.ts b/packages/eslint-plugin/tests/eslint-rules/no-implicit-globals.test.ts index 0add13fba05e..98eb8bc0b661 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-implicit-globals.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-implicit-globals.test.ts @@ -1,9 +1,3 @@ -'use strict'; - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from 'eslint/lib/rules/no-implicit-globals'; import RuleTester from '../RuleTester'; diff --git a/packages/eslint-plugin/tests/eslint-rules/no-redeclare.test.ts b/packages/eslint-plugin/tests/eslint-rules/no-redeclare.test.ts index 3a893df1dd00..35a84a4767db 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-redeclare.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-redeclare.test.ts @@ -1,9 +1,3 @@ -'use strict'; - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from 'eslint/lib/rules/no-redeclare'; import RuleTester from '../RuleTester'; diff --git a/packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.test.ts b/packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.test.ts index 48c2babd7024..18020fff8e32 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.test.ts @@ -1,9 +1,3 @@ -'use strict'; - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from 'eslint/lib/rules/no-restricted-globals'; import RuleTester from '../RuleTester'; diff --git a/packages/eslint-plugin/tests/eslint-rules/no-shadow.test.ts b/packages/eslint-plugin/tests/eslint-rules/no-shadow.test.ts index 0d65d2048872..aa4628db6993 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-shadow.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-shadow.test.ts @@ -1,9 +1,3 @@ -'use strict'; - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from 'eslint/lib/rules/no-shadow'; import RuleTester from '../RuleTester'; diff --git a/packages/eslint-plugin/tests/eslint-rules/no-undef.test.ts b/packages/eslint-plugin/tests/eslint-rules/no-undef.test.ts index 274a787b78a2..a245c87bf0e3 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-undef.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-undef.test.ts @@ -1,13 +1,3 @@ -/** - * @fileoverview Check internal rule - * @author Armano - */ -'use strict'; - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from 'eslint/lib/rules/no-undef'; import RuleTester from '../RuleTester'; diff --git a/packages/eslint-plugin/tests/eslint-rules/no-unused-vars.test.ts b/packages/eslint-plugin/tests/eslint-rules/no-unused-vars.test.ts index 73d9fbc06011..dd5436d48d3b 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-unused-vars.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-unused-vars.test.ts @@ -1,9 +1,3 @@ -'use strict'; - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from 'eslint/lib/rules/no-unused-vars'; import RuleTester from '../RuleTester'; diff --git a/packages/eslint-plugin/tests/eslint-rules/no-use-before-define.test.ts b/packages/eslint-plugin/tests/eslint-rules/no-use-before-define.test.ts index bf346fcfa2ef..e99e3f4db8ea 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-use-before-define.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-use-before-define.test.ts @@ -1,9 +1,3 @@ -'use strict'; - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from 'eslint/lib/rules/no-use-before-define'; import RuleTester from '../RuleTester'; diff --git a/packages/eslint-plugin/tests/eslint-rules/strict.test.ts b/packages/eslint-plugin/tests/eslint-rules/strict.test.ts index 83edab4f2145..48299fdfdf86 100644 --- a/packages/eslint-plugin/tests/eslint-rules/strict.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/strict.test.ts @@ -1,9 +1,3 @@ -'use strict'; - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from 'eslint/lib/rules/strict'; import RuleTester from '../RuleTester'; diff --git a/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.test.ts b/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.test.ts index f4b0557ec162..3f0b42128831 100644 --- a/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.test.ts +++ b/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.test.ts @@ -1,19 +1,6 @@ -/** - * @fileoverview Enforces member overloads to be consecutive. - * @author Patricio Trevino - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/adjacent-overload-signatures'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/array-type.test.ts b/packages/eslint-plugin/tests/rules/array-type.test.ts index 3036fe6783ff..fdb7976fae20 100644 --- a/packages/eslint-plugin/tests/rules/array-type.test.ts +++ b/packages/eslint-plugin/tests/rules/array-type.test.ts @@ -1,21 +1,6 @@ -/** - * @fileoverview Requires using either `T[]` or `Array` for arrays. - * @author Mackie Underdown - * @author Armano - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/array-type'; import RuleTester from '../RuleTester'; import { Linter } from 'eslint'; -import assert from 'assert'; - -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' @@ -837,7 +822,7 @@ describe('array-type (nested)', () => { } ); - assert.strictEqual(output, result.output); + expect(output).toBe(result.output); } testOutput( diff --git a/packages/eslint-plugin/tests/rules/ban-types.test.ts b/packages/eslint-plugin/tests/rules/ban-types.test.ts index 2aafd3334eaf..e9cc6afe8e07 100644 --- a/packages/eslint-plugin/tests/rules/ban-types.test.ts +++ b/packages/eslint-plugin/tests/rules/ban-types.test.ts @@ -1,20 +1,7 @@ -/** - * @fileoverview Enforces that types will not to be used - * @author Armano - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/ban-types'; import RuleTester from '../RuleTester'; import { InferOptionsTypeFromRule } from '../../src/util'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/camelcase.test.ts b/packages/eslint-plugin/tests/rules/camelcase.test.ts index 12a492f993c1..292982f9c40e 100644 --- a/packages/eslint-plugin/tests/rules/camelcase.test.ts +++ b/packages/eslint-plugin/tests/rules/camelcase.test.ts @@ -1,14 +1,3 @@ -/** - * @fileoverview Tests for camelcase rule - * @author Guy Lilian - * @author Shahar Or - * @author Patricio Trevino - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/camelcase'; import RuleTester from '../RuleTester'; @@ -16,10 +5,6 @@ const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - ruleTester.run('camelcase', rule, { valid: [ { diff --git a/packages/eslint-plugin/tests/rules/class-name-casing.test.ts b/packages/eslint-plugin/tests/rules/class-name-casing.test.ts index 980a609e74aa..2b9f1305e719 100644 --- a/packages/eslint-plugin/tests/rules/class-name-casing.test.ts +++ b/packages/eslint-plugin/tests/rules/class-name-casing.test.ts @@ -1,20 +1,6 @@ -/** - * @fileoverview Enforces PascalCased class and interface names. - * @author Jed Fox - * @author Armano - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/class-name-casing'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts b/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts index d17114dac7bf..1671f2773394 100644 --- a/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts +++ b/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts @@ -1,19 +1,6 @@ -/** - * @fileoverview Enforces explicit return type for functions - * @author Scott O'Hara - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/explicit-function-return-type'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts b/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts index b25dfc7e2b37..d8578c533e6f 100644 --- a/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts +++ b/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts @@ -1,19 +1,6 @@ -/** - * @fileoverview Enforces explicit accessibility modifiers for class members - * @author Danny Fritz - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/explicit-member-accessibility'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/generic-type-naming.test.ts b/packages/eslint-plugin/tests/rules/generic-type-naming.test.ts index 9231dcf88701..06ff1ed904e8 100644 --- a/packages/eslint-plugin/tests/rules/generic-type-naming.test.ts +++ b/packages/eslint-plugin/tests/rules/generic-type-naming.test.ts @@ -1,18 +1,6 @@ -/** - * @fileoverview Enforces naming of generic type variables. - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/generic-type-naming'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/indent.test.ts b/packages/eslint-plugin/tests/rules/indent.test.ts index fcf035426fee..f955e3aef7a8 100644 --- a/packages/eslint-plugin/tests/rules/indent.test.ts +++ b/packages/eslint-plugin/tests/rules/indent.test.ts @@ -1,13 +1,3 @@ -/** - * @fileoverview Check internal rule - * @author Armano - */ -'use strict'; - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/indent'; import RuleTester, { RunTests, TestCaseError } from '../RuleTester'; import { diff --git a/packages/eslint-plugin/tests/rules/interface-name-prefix.test.ts b/packages/eslint-plugin/tests/rules/interface-name-prefix.test.ts index 77cce0b06df2..7706ed842d60 100644 --- a/packages/eslint-plugin/tests/rules/interface-name-prefix.test.ts +++ b/packages/eslint-plugin/tests/rules/interface-name-prefix.test.ts @@ -1,19 +1,6 @@ -/** - * @fileoverview Enforces interface names are prefixed with "I" - * @author Danny Fritz - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/interface-name-prefix'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/member-delimiter-style.test.ts b/packages/eslint-plugin/tests/rules/member-delimiter-style.test.ts index d4ba193a4cef..80b2d152741c 100644 --- a/packages/eslint-plugin/tests/rules/member-delimiter-style.test.ts +++ b/packages/eslint-plugin/tests/rules/member-delimiter-style.test.ts @@ -1,20 +1,6 @@ -/** - * @fileoverview Enforces a member delimiter style in interfaces and type literals. - * @author Patricio Trevino - * @author Brad Zacher - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/member-delimiter-style'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/member-naming.test.ts b/packages/eslint-plugin/tests/rules/member-naming.test.ts index 2bab2df33c07..46365b432ec3 100644 --- a/packages/eslint-plugin/tests/rules/member-naming.test.ts +++ b/packages/eslint-plugin/tests/rules/member-naming.test.ts @@ -1,19 +1,6 @@ -/** - * @fileoverview Enforces naming conventions for class members by visibility. - * @author Ian MacLeod - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/member-naming'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/member-ordering.test.ts b/packages/eslint-plugin/tests/rules/member-ordering.test.ts index e5c5962af693..98170e07c749 100644 --- a/packages/eslint-plugin/tests/rules/member-ordering.test.ts +++ b/packages/eslint-plugin/tests/rules/member-ordering.test.ts @@ -1,19 +1,6 @@ -/** - * @fileoverview Enforces a standard member declaration order. - * @author Patricio Trevino - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/member-ordering'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/no-angle-bracket-type-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-angle-bracket-type-assertion.test.ts index e44aa4a85c2b..f978aaaa75ed 100644 --- a/packages/eslint-plugin/tests/rules/no-angle-bracket-type-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-angle-bracket-type-assertion.test.ts @@ -1,19 +1,6 @@ -/** - * @fileoverview Requires the use of as Type for type assertions instead of - * @author Patricio Trevino - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/no-angle-bracket-type-assertion'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/no-array-constructor.test.ts b/packages/eslint-plugin/tests/rules/no-array-constructor.test.ts index f0c0fda1639d..6efdd6ab041f 100644 --- a/packages/eslint-plugin/tests/rules/no-array-constructor.test.ts +++ b/packages/eslint-plugin/tests/rules/no-array-constructor.test.ts @@ -1,20 +1,6 @@ -/** - * @fileoverview disallow generic `Array` constructors - * @author Jed Fox - * @author Matt DuVall - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/no-array-constructor'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts b/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts index 4c02ca466520..ff7c1c5d6161 100644 --- a/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts +++ b/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts @@ -1,19 +1,6 @@ -/** - * @fileoverview Disallows the declaration of empty interfaces. - * @author Patricio Trevino - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/no-empty-interface'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/no-explicit-any.test.ts b/packages/eslint-plugin/tests/rules/no-explicit-any.test.ts index a4e9db77fc66..7da776f07efa 100644 --- a/packages/eslint-plugin/tests/rules/no-explicit-any.test.ts +++ b/packages/eslint-plugin/tests/rules/no-explicit-any.test.ts @@ -1,19 +1,6 @@ -/** - * @fileoverview Enforces the any type is not used - * @author Danny Fritz - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/no-explicit-any'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/no-extraneous-class.test.ts b/packages/eslint-plugin/tests/rules/no-extraneous-class.test.ts index d7021841454e..ffcd17cc8395 100644 --- a/packages/eslint-plugin/tests/rules/no-extraneous-class.test.ts +++ b/packages/eslint-plugin/tests/rules/no-extraneous-class.test.ts @@ -1,13 +1,3 @@ -/** - * @fileoverview Forbids the use of classes as namespaces - * Some tests adapted from https://github.com/palantir/tslint/tree/c7fc99b5/test/rules/no-unnecessary-class - * @author Jed Fox - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/no-extraneous-class'; import RuleTester from '../RuleTester'; @@ -21,10 +11,6 @@ const onlyConstructor = { messageId: 'onlyConstructor' as 'onlyConstructor' }; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/no-inferrable-types.test.ts b/packages/eslint-plugin/tests/rules/no-inferrable-types.test.ts index 152ed4393bbf..0999c66a6e06 100644 --- a/packages/eslint-plugin/tests/rules/no-inferrable-types.test.ts +++ b/packages/eslint-plugin/tests/rules/no-inferrable-types.test.ts @@ -1,19 +1,6 @@ -/** - * @fileoverview Disallows explicit type declarations for inferrable types - * @author James Garbutt - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/no-inferrable-types'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/no-misused-new.test.ts b/packages/eslint-plugin/tests/rules/no-misused-new.test.ts index 708b8a588a0a..3d5c64592c4e 100644 --- a/packages/eslint-plugin/tests/rules/no-misused-new.test.ts +++ b/packages/eslint-plugin/tests/rules/no-misused-new.test.ts @@ -1,19 +1,6 @@ -/** - * @fileoverview Enforce valid definition of `new` and `constructor`. - * @author Armano - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/no-misused-new'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/no-namespace.test.ts b/packages/eslint-plugin/tests/rules/no-namespace.test.ts index 951c22c69201..446060421086 100644 --- a/packages/eslint-plugin/tests/rules/no-namespace.test.ts +++ b/packages/eslint-plugin/tests/rules/no-namespace.test.ts @@ -1,19 +1,6 @@ -/** - * @fileoverview Disallows the use of custom TypeScript modules and namespaces. - * @author Patricio Trevino - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/no-namespace'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts index 32a03cd4fff0..d33c2a671f19 100644 --- a/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts @@ -1,19 +1,6 @@ -/** - * @fileoverview Disallows non-null assertions using the `!` postfix operator. - * @author Macklin Underdown - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/no-non-null-assertion'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/no-object-literal-type-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-object-literal-type-assertion.test.ts index f17624d196e9..83c577932542 100644 --- a/packages/eslint-plugin/tests/rules/no-object-literal-type-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-object-literal-type-assertion.test.ts @@ -1,19 +1,6 @@ -/** - * @fileoverview Forbids an object literal to appear in a type assertion expression - * @author Armano - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/no-object-literal-type-assertion'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', parserOptions: { diff --git a/packages/eslint-plugin/tests/rules/no-parameter-properties.test.ts b/packages/eslint-plugin/tests/rules/no-parameter-properties.test.ts index ef63f2bea662..033539a1acba 100644 --- a/packages/eslint-plugin/tests/rules/no-parameter-properties.test.ts +++ b/packages/eslint-plugin/tests/rules/no-parameter-properties.test.ts @@ -1,19 +1,6 @@ -/** - * @fileoverview Disallows parameter properties in class constructors. - * @author Patricio Trevino - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/no-parameter-properties'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/no-this-alias.test.ts b/packages/eslint-plugin/tests/rules/no-this-alias.test.ts index 1573d23f9039..34150830c18c 100644 --- a/packages/eslint-plugin/tests/rules/no-this-alias.test.ts +++ b/packages/eslint-plugin/tests/rules/no-this-alias.test.ts @@ -1,13 +1,3 @@ -/** - * @fileoverview Disallow aliasing `this` - * Some tests taken from TSLint: https://github.com/palantir/tslint/tree/c7fc99b5/test/rules/no-this-assignment - * @author Jed Fox - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; import rule from '../../src/rules/no-this-alias'; import RuleTester from '../RuleTester'; @@ -25,10 +15,6 @@ const arrayDestructureError = { type: AST_NODE_TYPES.ArrayPattern }; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/no-triple-slash-reference.test.ts b/packages/eslint-plugin/tests/rules/no-triple-slash-reference.test.ts index 80eb43061cd0..5b3860fd49fd 100644 --- a/packages/eslint-plugin/tests/rules/no-triple-slash-reference.test.ts +++ b/packages/eslint-plugin/tests/rules/no-triple-slash-reference.test.ts @@ -1,19 +1,6 @@ -/** - * @fileoverview Enforces triple slash references are not used - * @author Danny Fritz - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/no-triple-slash-reference'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/no-type-alias.test.ts b/packages/eslint-plugin/tests/rules/no-type-alias.test.ts index 5b097e8973d9..6607e70a512f 100644 --- a/packages/eslint-plugin/tests/rules/no-type-alias.test.ts +++ b/packages/eslint-plugin/tests/rules/no-type-alias.test.ts @@ -1,19 +1,6 @@ -/** - * @fileoverview Disallows the use of type aliases. - * @author Patricio Trevino - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/no-type-alias'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts index 2f826bd21838..7ee6bc5212c8 100644 --- a/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts @@ -1,21 +1,7 @@ -/** - * @fileoverview Warns if a type assertion does not change the type of an expression. - * @author Benjamin Lichtman - */ -'use strict'; - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import path from 'path'; import rule from '../../src/rules/no-unnecessary-type-assertion'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const rootDir = path.join(process.cwd(), 'tests/fixtures'); const parserOptions = { ecmaVersion: 2015, diff --git a/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts b/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts index 2f52aa3a4b0b..4d5a16e4da7e 100644 --- a/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts @@ -1,12 +1,3 @@ -/** - * @fileoverview Prevent variables used in TypeScript being marked as unused - * @author James Henry - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/no-unused-vars'; import RuleTester from '../RuleTester'; @@ -19,10 +10,6 @@ const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - // the base rule doesn't have messageIds function error( messages: { message: string; line: number; column: number }[] diff --git a/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts b/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts index 0e81aa408ca9..286b3115a20b 100644 --- a/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts +++ b/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts @@ -1,21 +1,7 @@ -/** - * @fileoverview Tests for no-use-before-define rule. - * @author Ilya Volodin - * @author Jed Fox - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/no-use-before-define'; import RuleTester from '../RuleTester'; import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/no-useless-constructor.test.ts b/packages/eslint-plugin/tests/rules/no-useless-constructor.test.ts index 6ece0d970ae5..05320c9962b7 100644 --- a/packages/eslint-plugin/tests/rules/no-useless-constructor.test.ts +++ b/packages/eslint-plugin/tests/rules/no-useless-constructor.test.ts @@ -1,9 +1,3 @@ -'use strict'; - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/no-useless-constructor'; import RuleTester from '../RuleTester'; diff --git a/packages/eslint-plugin/tests/rules/no-var-requires.test.ts b/packages/eslint-plugin/tests/rules/no-var-requires.test.ts index 96227fcb3095..b7514271aa55 100644 --- a/packages/eslint-plugin/tests/rules/no-var-requires.test.ts +++ b/packages/eslint-plugin/tests/rules/no-var-requires.test.ts @@ -1,19 +1,6 @@ -/** - * @fileoverview Disallows the use of require statements except in import statements. - * @author Macklin Underdown - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/no-var-requires'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/prefer-interface.test.ts b/packages/eslint-plugin/tests/rules/prefer-interface.test.ts index f48cb2f57cb3..05e08b04f61d 100644 --- a/packages/eslint-plugin/tests/rules/prefer-interface.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-interface.test.ts @@ -1,19 +1,6 @@ -/** - * @fileoverview Prefer an interface declaration over a type literal (type T = { ... }) - * @author Armano - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/prefer-interface'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/prefer-namespace-keyword.test.ts b/packages/eslint-plugin/tests/rules/prefer-namespace-keyword.test.ts index c8025a248552..847c09fc4f79 100644 --- a/packages/eslint-plugin/tests/rules/prefer-namespace-keyword.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-namespace-keyword.test.ts @@ -1,20 +1,6 @@ -/** - * @fileoverview Enforces the use of the keyword `namespace` over `module` to declare custom TypeScript modules. - * @author Patricio Trevino - * @author Armano - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/prefer-namespace-keyword'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); diff --git a/packages/eslint-plugin/tests/rules/restrict-plus-operands.test.ts b/packages/eslint-plugin/tests/rules/restrict-plus-operands.test.ts index e1a65a87bb40..6c0be726602c 100644 --- a/packages/eslint-plugin/tests/rules/restrict-plus-operands.test.ts +++ b/packages/eslint-plugin/tests/rules/restrict-plus-operands.test.ts @@ -1,21 +1,7 @@ -/** - * @fileoverview When adding two variables, operands must both be of type number or of type string. - * @author James Henry - * @author Armano - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ -const path = require('path'); - +import path from 'path'; import rule from '../../src/rules/restrict-plus-operands'; import RuleTester from '../RuleTester'; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const rootPath = path.join(process.cwd(), 'tests/fixtures/'); const ruleTester = new RuleTester({ diff --git a/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts index dbd5b034f248..2f4b43fda7c5 100644 --- a/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts @@ -1,12 +1,3 @@ -/** - * @fileoverview Enforces spacing around type annotations - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - import rule from '../../src/rules/type-annotation-spacing'; import RuleTester, { InvalidTestCase, ValidTestCase } from '../RuleTester'; import { @@ -17,10 +8,6 @@ import { type MessageIds = InferMessageIdsTypeFromRule; type Options = InferOptionsTypeFromRule; -//------------------------------------------------------------------------------ -// Tests -//------------------------------------------------------------------------------ - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' }); From 419ccde34a7090d9ef719b888ae9209c68f97642 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Wed, 6 Feb 2019 11:10:22 -0800 Subject: [PATCH 78/92] move parser ambient typings to fix the build --- packages/eslint-plugin/tsconfig.build.json | 7 ++++++- packages/eslint-plugin/tsconfig.json | 2 ++ packages/parser/tsconfig.build.json | 2 +- packages/parser/tsconfig.json | 1 + .../parser/{src/typings.d.ts => typings/eslint-scope.d.ts} | 6 ++++++ 5 files changed, 16 insertions(+), 2 deletions(-) rename packages/parser/{src/typings.d.ts => typings/eslint-scope.d.ts} (97%) diff --git a/packages/eslint-plugin/tsconfig.build.json b/packages/eslint-plugin/tsconfig.build.json index c284ed71fc99..1d2cae4d3dc4 100644 --- a/packages/eslint-plugin/tsconfig.build.json +++ b/packages/eslint-plugin/tsconfig.build.json @@ -7,5 +7,10 @@ "outDir": "./dist", "resolveJsonModule": true, }, - "include": ["src", "typings"], + "include": [ + "src", + "typings", + // include the parser's ambient typings because the parser exports them in its type defs + "../parser/typings", + ], } diff --git a/packages/eslint-plugin/tsconfig.json b/packages/eslint-plugin/tsconfig.json index 52a6a092b0a3..3b580bd3a5fe 100644 --- a/packages/eslint-plugin/tsconfig.json +++ b/packages/eslint-plugin/tsconfig.json @@ -3,6 +3,8 @@ "include": [ "src", "typings", + // include the parser's ambient typings because the parser exports them in its type defs + "../parser/typings", "tests", "tools", ], diff --git a/packages/parser/tsconfig.build.json b/packages/parser/tsconfig.build.json index 1e3450ecc1e8..06801a8444e9 100644 --- a/packages/parser/tsconfig.build.json +++ b/packages/parser/tsconfig.build.json @@ -4,5 +4,5 @@ "declaration": true, "outDir": "./dist", }, - "include": ["src"], + "include": ["src", "typings"], } diff --git a/packages/parser/tsconfig.json b/packages/parser/tsconfig.json index 079001c0aa01..a02b01d72b7e 100644 --- a/packages/parser/tsconfig.json +++ b/packages/parser/tsconfig.json @@ -2,6 +2,7 @@ "extends": "./tsconfig.build.json", "include": [ "src", + "typings", "tests", "tools", ], diff --git a/packages/parser/src/typings.d.ts b/packages/parser/typings/eslint-scope.d.ts similarity index 97% rename from packages/parser/src/typings.d.ts rename to packages/parser/typings/eslint-scope.d.ts index 08f92526c823..aff831030e77 100644 --- a/packages/parser/src/typings.d.ts +++ b/packages/parser/typings/eslint-scope.d.ts @@ -1,6 +1,12 @@ // Type definitions for eslint-scope 4.0.0 // Project: http://github.com/eslint/eslint-scope // Definitions by: Armano + +//----------------------------------------------------------------------- +// TODO - figure out how to make ScopeManager exportable so that +// the module's type declaration files don't break +//----------------------------------------------------------------------- + declare module 'eslint-scope/lib/options' { export type PatternVisitorCallback = (pattern: any, info: any) => void; From 0ac7c7f2401969b225ee010e5bcb357ef87f9e33 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Wed, 6 Feb 2019 11:21:45 -0800 Subject: [PATCH 79/92] Fix up some raw strings instead of enum usage --- .../eslint-plugin/src/rules/array-type.ts | 6 +- packages/eslint-plugin/src/rules/camelcase.ts | 8 +- packages/eslint-plugin/src/rules/indent.ts | 114 +++++++++--------- .../src/rules/member-ordering.ts | 4 +- .../eslint-plugin/src/rules/no-type-alias.ts | 6 +- 5 files changed, 71 insertions(+), 67 deletions(-) diff --git a/packages/eslint-plugin/src/rules/array-type.ts b/packages/eslint-plugin/src/rules/array-type.ts index fe2e3d2fe048..4baf51fb4aac 100644 --- a/packages/eslint-plugin/src/rules/array-type.ts +++ b/packages/eslint-plugin/src/rules/array-type.ts @@ -32,7 +32,7 @@ function isSimpleType(node: TSESTree.Node): boolean { case AST_NODE_TYPES.TSTypeReference: if ( node.typeName && - node.typeName.type === 'Identifier' && + node.typeName.type === AST_NODE_TYPES.Identifier && node.typeName.name === 'Array' ) { if (!node.typeParameters) { @@ -132,7 +132,7 @@ export default util.createRule({ */ function getMessageType(node: TSESTree.Node): string { if (node) { - if (node.type === 'TSParenthesizedType') { + if (node.type === AST_NODE_TYPES.TSParenthesizedType) { return getMessageType(node.typeAnnotation); } if (isSimpleType(node)) { @@ -186,7 +186,7 @@ export default util.createRule({ TSTypeReference(node: TSESTree.TSTypeReference) { if ( option === 'generic' || - node.typeName.type !== 'Identifier' || + node.typeName.type !== AST_NODE_TYPES.Identifier || node.typeName.name !== 'Array' ) { return; diff --git a/packages/eslint-plugin/src/rules/camelcase.ts b/packages/eslint-plugin/src/rules/camelcase.ts index 80cae436b8b9..42285f2b0bee 100644 --- a/packages/eslint-plugin/src/rules/camelcase.ts +++ b/packages/eslint-plugin/src/rules/camelcase.ts @@ -32,10 +32,10 @@ export default util.createRule({ create(context, [options]) { const rules = baseRule.create(context); const TS_PROPERTY_TYPES = [ - 'TSPropertySignature', - 'ClassProperty', - 'TSParameterProperty', - 'TSAbstractClassProperty' + AST_NODE_TYPES.TSPropertySignature, + AST_NODE_TYPES.ClassProperty, + AST_NODE_TYPES.TSParameterProperty, + AST_NODE_TYPES.TSAbstractClassProperty ]; const properties = options.properties; diff --git a/packages/eslint-plugin/src/rules/indent.ts b/packages/eslint-plugin/src/rules/indent.ts index 367f2fc6d010..3ab9227c4b89 100644 --- a/packages/eslint-plugin/src/rules/indent.ts +++ b/packages/eslint-plugin/src/rules/indent.ts @@ -15,69 +15,69 @@ type MessageIds = util.InferMessageIdsTypeFromRule; const KNOWN_NODES = new Set([ // Class properties aren't yet supported by eslint... - 'ClassProperty', + AST_NODE_TYPES.ClassProperty, // ts keywords - 'TSAbstractKeyword', - 'TSAnyKeyword', - 'TSBooleanKeyword', - 'TSNeverKeyword', - 'TSNumberKeyword', - 'TSStringKeyword', - 'TSSymbolKeyword', - 'TSUndefinedKeyword', - 'TSUnknownKeyword', - 'TSVoidKeyword', - 'TSNullKeyword', + AST_NODE_TYPES.TSAbstractKeyword, + AST_NODE_TYPES.TSAnyKeyword, + AST_NODE_TYPES.TSBooleanKeyword, + AST_NODE_TYPES.TSNeverKeyword, + AST_NODE_TYPES.TSNumberKeyword, + AST_NODE_TYPES.TSStringKeyword, + AST_NODE_TYPES.TSSymbolKeyword, + AST_NODE_TYPES.TSUndefinedKeyword, + AST_NODE_TYPES.TSUnknownKeyword, + AST_NODE_TYPES.TSVoidKeyword, + AST_NODE_TYPES.TSNullKeyword, // ts specific nodes we want to support - 'TSAbstractClassProperty', - 'TSAbstractMethodDefinition', - 'TSArrayType', - 'TSAsExpression', - 'TSCallSignatureDeclaration', - 'TSConditionalType', - 'TSConstructorType', - 'TSConstructSignatureDeclaration', - 'TSDeclareFunction', - 'TSEmptyBodyFunctionExpression', - 'TSEnumDeclaration', - 'TSEnumMember', - 'TSExportAssignment', - 'TSExternalModuleReference', - 'TSFunctionType', - 'TSImportType', - 'TSIndexedAccessType', - 'TSIndexSignature', - 'TSInferType', - 'TSInterfaceBody', - 'TSInterfaceDeclaration', - 'TSInterfaceHeritage', - 'TSIntersectionType', - 'TSImportEqualsDeclaration', - 'TSLiteralType', - 'TSMappedType', - 'TSMethodSignature', + AST_NODE_TYPES.TSAbstractClassProperty, + AST_NODE_TYPES.TSAbstractMethodDefinition, + AST_NODE_TYPES.TSArrayType, + AST_NODE_TYPES.TSAsExpression, + AST_NODE_TYPES.TSCallSignatureDeclaration, + AST_NODE_TYPES.TSConditionalType, + AST_NODE_TYPES.TSConstructorType, + AST_NODE_TYPES.TSConstructSignatureDeclaration, + AST_NODE_TYPES.TSDeclareFunction, + AST_NODE_TYPES.TSEmptyBodyFunctionExpression, + AST_NODE_TYPES.TSEnumDeclaration, + AST_NODE_TYPES.TSEnumMember, + AST_NODE_TYPES.TSExportAssignment, + AST_NODE_TYPES.TSExternalModuleReference, + AST_NODE_TYPES.TSFunctionType, + AST_NODE_TYPES.TSImportType, + AST_NODE_TYPES.TSIndexedAccessType, + AST_NODE_TYPES.TSIndexSignature, + AST_NODE_TYPES.TSInferType, + AST_NODE_TYPES.TSInterfaceBody, + AST_NODE_TYPES.TSInterfaceDeclaration, + AST_NODE_TYPES.TSInterfaceHeritage, + AST_NODE_TYPES.TSIntersectionType, + AST_NODE_TYPES.TSImportEqualsDeclaration, + AST_NODE_TYPES.TSLiteralType, + AST_NODE_TYPES.TSMappedType, + AST_NODE_TYPES.TSMethodSignature, 'TSMinusToken', - 'TSModuleBlock', - 'TSModuleDeclaration', - 'TSNonNullExpression', - 'TSParameterProperty', - 'TSParenthesizedType', + AST_NODE_TYPES.TSModuleBlock, + AST_NODE_TYPES.TSModuleDeclaration, + AST_NODE_TYPES.TSNonNullExpression, + AST_NODE_TYPES.TSParameterProperty, + AST_NODE_TYPES.TSParenthesizedType, 'TSPlusToken', - 'TSPropertySignature', - 'TSQualifiedName', - 'TSQuestionToken', - 'TSRestType', - 'TSThisType', - 'TSTupleType', - 'TSTypeAnnotation', - 'TSTypeLiteral', - 'TSTypeOperator', - 'TSTypeParameter', - 'TSTypeParameterDeclaration', - 'TSTypeReference', - 'TSUnionType' + AST_NODE_TYPES.TSPropertySignature, + AST_NODE_TYPES.TSQualifiedName, + AST_NODE_TYPES.TSQuestionToken, + AST_NODE_TYPES.TSRestType, + AST_NODE_TYPES.TSThisType, + AST_NODE_TYPES.TSTupleType, + AST_NODE_TYPES.TSTypeAnnotation, + AST_NODE_TYPES.TSTypeLiteral, + AST_NODE_TYPES.TSTypeOperator, + AST_NODE_TYPES.TSTypeParameter, + AST_NODE_TYPES.TSTypeParameterDeclaration, + AST_NODE_TYPES.TSTypeReference, + AST_NODE_TYPES.TSUnionType ]); export default util.createRule({ diff --git a/packages/eslint-plugin/src/rules/member-ordering.ts b/packages/eslint-plugin/src/rules/member-ordering.ts index f93ddac2ee61..b16c878bc718 100644 --- a/packages/eslint-plugin/src/rules/member-ordering.ts +++ b/packages/eslint-plugin/src/rules/member-ordering.ts @@ -170,8 +170,8 @@ export default util.createRule({ ], create(context, [options]) { const functionExpressions = [ - 'FunctionExpression', - 'ArrowFunctionExpression' + AST_NODE_TYPES.FunctionExpression, + AST_NODE_TYPES.ArrowFunctionExpression ]; /** diff --git a/packages/eslint-plugin/src/rules/no-type-alias.ts b/packages/eslint-plugin/src/rules/no-type-alias.ts index 41ebcaa0aa4e..d73d436a0022 100644 --- a/packages/eslint-plugin/src/rules/no-type-alias.ts +++ b/packages/eslint-plugin/src/rules/no-type-alias.ts @@ -109,7 +109,11 @@ export default util.createRule({ 'in-intersections', 'in-unions-and-intersections' ]; - const aliasTypes = ['TSArrayType', 'TSTypeReference', 'TSLiteralType']; + const aliasTypes = [ + AST_NODE_TYPES.TSArrayType, + AST_NODE_TYPES.TSTypeReference, + AST_NODE_TYPES.TSLiteralType + ]; type CompositionType = TSESTree.TSUnionType | TSESTree.TSIntersectionType; /** From 46613cc4e0d1d4484e79ecd636af42882bbae6ff Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Wed, 6 Feb 2019 11:22:48 -0800 Subject: [PATCH 80/92] ran yarn format --- .../eslint-plugin-tslint/tsconfig.build.json | 4 +- packages/eslint-plugin-tslint/tsconfig.json | 10 +-- packages/eslint-plugin/jest.config.js | 4 +- .../src/configs/recommended.json | 78 +++++++++---------- packages/eslint-plugin/tsconfig.build.json | 6 +- packages/eslint-plugin/tsconfig.json | 4 +- packages/parser/tsconfig.build.json | 4 +- packages/parser/tsconfig.json | 11 +-- .../typescript-estree/tsconfig.build.json | 4 +- packages/typescript-estree/tsconfig.json | 6 +- tsconfig.json | 2 +- 11 files changed, 57 insertions(+), 76 deletions(-) diff --git a/packages/eslint-plugin-tslint/tsconfig.build.json b/packages/eslint-plugin-tslint/tsconfig.build.json index b89aec90074d..b1224f98e68b 100644 --- a/packages/eslint-plugin-tslint/tsconfig.build.json +++ b/packages/eslint-plugin-tslint/tsconfig.build.json @@ -1,7 +1,7 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "./dist", + "outDir": "./dist" }, - "include": ["src"], + "include": ["src"] } diff --git a/packages/eslint-plugin-tslint/tsconfig.json b/packages/eslint-plugin-tslint/tsconfig.json index b86222d3cccc..7db2d0520ffa 100644 --- a/packages/eslint-plugin-tslint/tsconfig.json +++ b/packages/eslint-plugin-tslint/tsconfig.json @@ -1,11 +1,5 @@ { "extends": "./tsconfig.build.json", - "include": [ - "src", - "tests", - ], - "exclude": [ - "tests/test-project", - "tests/test-tslint-rules-directory", - ], + "include": ["src", "tests"], + "exclude": ["tests/test-project", "tests/test-tslint-rules-directory"] } diff --git a/packages/eslint-plugin/jest.config.js b/packages/eslint-plugin/jest.config.js index aa3dbff5b8b7..2d32f23761a3 100644 --- a/packages/eslint-plugin/jest.config.js +++ b/packages/eslint-plugin/jest.config.js @@ -4,8 +4,8 @@ module.exports = { globals: { 'ts-jest': { // TODO - re-enable type checking when the build is working - isolatedModules: true, - }, + isolatedModules: true + } }, testEnvironment: 'node', transform: { diff --git a/packages/eslint-plugin/src/configs/recommended.json b/packages/eslint-plugin/src/configs/recommended.json index 4cdd013a1074..e107a6457248 100644 --- a/packages/eslint-plugin/src/configs/recommended.json +++ b/packages/eslint-plugin/src/configs/recommended.json @@ -1,42 +1,40 @@ { - "parser": "@typescript-eslint/parser", - "parserOptions": { - "sourceType": "module" - }, - "plugins": [ - "@typescript-eslint" - ], - "rules": { - "@typescript-eslint/adjacent-overload-signatures": "error", - "@typescript-eslint/array-type": "error", - "@typescript-eslint/ban-types": "error", - "camelcase": "off", - "@typescript-eslint/camelcase": "error", - "@typescript-eslint/class-name-casing": "error", - "@typescript-eslint/explicit-function-return-type": "warn", - "@typescript-eslint/explicit-member-accessibility": "error", - "indent": "off", - "@typescript-eslint/indent": "error", - "@typescript-eslint/interface-name-prefix": "error", - "@typescript-eslint/member-delimiter-style": "error", - "@typescript-eslint/no-angle-bracket-type-assertion": "error", - "no-array-constructor": "off", - "@typescript-eslint/no-array-constructor": "error", - "@typescript-eslint/no-empty-interface": "error", - "@typescript-eslint/no-explicit-any": "warn", - "@typescript-eslint/no-inferrable-types": "error", - "@typescript-eslint/no-misused-new": "error", - "@typescript-eslint/no-namespace": "error", - "@typescript-eslint/no-non-null-assertion": "error", - "@typescript-eslint/no-object-literal-type-assertion": "error", - "@typescript-eslint/no-parameter-properties": "error", - "@typescript-eslint/no-triple-slash-reference": "error", - "no-unused-vars": "off", - "@typescript-eslint/no-unused-vars": "warn", - "@typescript-eslint/no-use-before-define": "error", - "@typescript-eslint/no-var-requires": "error", - "@typescript-eslint/prefer-interface": "error", - "@typescript-eslint/prefer-namespace-keyword": "error", - "@typescript-eslint/type-annotation-spacing": "error" - } + "parser": "@typescript-eslint/parser", + "parserOptions": { + "sourceType": "module" + }, + "plugins": ["@typescript-eslint"], + "rules": { + "@typescript-eslint/adjacent-overload-signatures": "error", + "@typescript-eslint/array-type": "error", + "@typescript-eslint/ban-types": "error", + "camelcase": "off", + "@typescript-eslint/camelcase": "error", + "@typescript-eslint/class-name-casing": "error", + "@typescript-eslint/explicit-function-return-type": "warn", + "@typescript-eslint/explicit-member-accessibility": "error", + "indent": "off", + "@typescript-eslint/indent": "error", + "@typescript-eslint/interface-name-prefix": "error", + "@typescript-eslint/member-delimiter-style": "error", + "@typescript-eslint/no-angle-bracket-type-assertion": "error", + "no-array-constructor": "off", + "@typescript-eslint/no-array-constructor": "error", + "@typescript-eslint/no-empty-interface": "error", + "@typescript-eslint/no-explicit-any": "warn", + "@typescript-eslint/no-inferrable-types": "error", + "@typescript-eslint/no-misused-new": "error", + "@typescript-eslint/no-namespace": "error", + "@typescript-eslint/no-non-null-assertion": "error", + "@typescript-eslint/no-object-literal-type-assertion": "error", + "@typescript-eslint/no-parameter-properties": "error", + "@typescript-eslint/no-triple-slash-reference": "error", + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": "warn", + "@typescript-eslint/no-use-before-define": "error", + "@typescript-eslint/no-var-requires": "error", + "@typescript-eslint/prefer-interface": "error", + "@typescript-eslint/prefer-namespace-keyword": "error", + "@typescript-eslint/type-annotation-spacing": "error" + } } diff --git a/packages/eslint-plugin/tsconfig.build.json b/packages/eslint-plugin/tsconfig.build.json index 1d2cae4d3dc4..304db267ae6e 100644 --- a/packages/eslint-plugin/tsconfig.build.json +++ b/packages/eslint-plugin/tsconfig.build.json @@ -5,12 +5,12 @@ "declaration": false, "declarationMap": false, "outDir": "./dist", - "resolveJsonModule": true, + "resolveJsonModule": true }, "include": [ "src", "typings", // include the parser's ambient typings because the parser exports them in its type defs - "../parser/typings", - ], + "../parser/typings" + ] } diff --git a/packages/eslint-plugin/tsconfig.json b/packages/eslint-plugin/tsconfig.json index 3b580bd3a5fe..fc93e91c26d3 100644 --- a/packages/eslint-plugin/tsconfig.json +++ b/packages/eslint-plugin/tsconfig.json @@ -6,6 +6,6 @@ // include the parser's ambient typings because the parser exports them in its type defs "../parser/typings", "tests", - "tools", - ], + "tools" + ] } diff --git a/packages/parser/tsconfig.build.json b/packages/parser/tsconfig.build.json index 06801a8444e9..8b51ca27bda3 100644 --- a/packages/parser/tsconfig.build.json +++ b/packages/parser/tsconfig.build.json @@ -2,7 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "declaration": true, - "outDir": "./dist", + "outDir": "./dist" }, - "include": ["src", "typings"], + "include": ["src", "typings"] } diff --git a/packages/parser/tsconfig.json b/packages/parser/tsconfig.json index a02b01d72b7e..58599d3d3ed5 100644 --- a/packages/parser/tsconfig.json +++ b/packages/parser/tsconfig.json @@ -1,12 +1,5 @@ { "extends": "./tsconfig.build.json", - "include": [ - "src", - "typings", - "tests", - "tools", - ], - "exclude": [ - "tests/fixtures", - ], + "include": ["src", "typings", "tests", "tools"], + "exclude": ["tests/fixtures"] } diff --git a/packages/typescript-estree/tsconfig.build.json b/packages/typescript-estree/tsconfig.build.json index b89aec90074d..b1224f98e68b 100644 --- a/packages/typescript-estree/tsconfig.build.json +++ b/packages/typescript-estree/tsconfig.build.json @@ -1,7 +1,7 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "./dist", + "outDir": "./dist" }, - "include": ["src"], + "include": ["src"] } diff --git a/packages/typescript-estree/tsconfig.json b/packages/typescript-estree/tsconfig.json index 33e188f86981..1fdde9ad21c5 100644 --- a/packages/typescript-estree/tsconfig.json +++ b/packages/typescript-estree/tsconfig.json @@ -1,8 +1,4 @@ { "extends": "./tsconfig.build.json", - "include": [ - "src", - "tests", - "tools", - ], + "include": ["src", "tests", "tools"] } diff --git a/tsconfig.json b/tsconfig.json index 1c0243d8bb15..fe87d8e95ab8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,6 +14,6 @@ "pretty": true, "sourceMap": true, "strict": true, - "target": "es2017", + "target": "es2017" } } From ca20023b6ac73c4ea2a33a9ceecc184ca7cf788e Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Wed, 6 Feb 2019 11:34:32 -0800 Subject: [PATCH 81/92] remove temporary isolated modules in tests --- packages/eslint-plugin/jest.config.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/eslint-plugin/jest.config.js b/packages/eslint-plugin/jest.config.js index 2d32f23761a3..2210a4dcb891 100644 --- a/packages/eslint-plugin/jest.config.js +++ b/packages/eslint-plugin/jest.config.js @@ -1,12 +1,6 @@ 'use strict'; module.exports = { - globals: { - 'ts-jest': { - // TODO - re-enable type checking when the build is working - isolatedModules: true - } - }, testEnvironment: 'node', transform: { '^.+\\.tsx?$': 'ts-jest' From ed6ed5e540e4cf8bfffc807d75541ac0f607fb1e Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Wed, 6 Feb 2019 16:54:42 -0800 Subject: [PATCH 82/92] review fixes --- .vscode/settings.json | 2 +- .../src/rules/no-inferrable-types.ts | 4 - .../tests/rules/no-misused-new.test.ts | 5 ++ packages/eslint-plugin/typings/ts-eslint.d.ts | 90 ++++++++++--------- 4 files changed, 54 insertions(+), 47 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 2c4de8650a59..adcf2422e8f3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -18,7 +18,7 @@ "files.trimTrailingWhitespace": true, // typescript auto-format settings -"typescript.tsdk": "node_modules/typescript/lib", + "typescript.tsdk": "node_modules/typescript/lib", "javascript.preferences.importModuleSpecifier": "auto", "typescript.preferences.importModuleSpecifier": "auto", "javascript.preferences.quoteStyle": "single", diff --git a/packages/eslint-plugin/src/rules/no-inferrable-types.ts b/packages/eslint-plugin/src/rules/no-inferrable-types.ts index 172335302886..4f695c996c1a 100644 --- a/packages/eslint-plugin/src/rules/no-inferrable-types.ts +++ b/packages/eslint-plugin/src/rules/no-inferrable-types.ts @@ -68,10 +68,6 @@ export default util.createRule({ return false; } - if (!init) { - return false; - } - const annotation = node.typeAnnotation; if (annotation.type === AST_NODE_TYPES.TSStringKeyword) { diff --git a/packages/eslint-plugin/tests/rules/no-misused-new.test.ts b/packages/eslint-plugin/tests/rules/no-misused-new.test.ts index 3d5c64592c4e..00d1d0f07f04 100644 --- a/packages/eslint-plugin/tests/rules/no-misused-new.test.ts +++ b/packages/eslint-plugin/tests/rules/no-misused-new.test.ts @@ -41,6 +41,11 @@ interface I { ` type T = { new(): T; +} + `, + ` +export default class { + constructor(); } ` ], diff --git a/packages/eslint-plugin/typings/ts-eslint.d.ts b/packages/eslint-plugin/typings/ts-eslint.d.ts index 68dd91e365f9..f12cdf6339b4 100644 --- a/packages/eslint-plugin/typings/ts-eslint.d.ts +++ b/packages/eslint-plugin/typings/ts-eslint.d.ts @@ -29,7 +29,7 @@ declare module 'ts-eslint' { } export type FilterPredicate = ( - tokenOrComment: AST.Token | TSESTree.Comment + tokenOrComment: TSESTree.Token | TSESTree.Comment ) => boolean; export type CursorWithSkipOptions = @@ -80,11 +80,14 @@ declare module 'ts-eslint' { node: TSESTree.Node ): { leading: TSESTree.Comment[]; trailing: TSESTree.Comment[] }; - getJSDocComment(node: TSESTree.Node): AST.Token | null; + getJSDocComment(node: TSESTree.Node): TSESTree.Node | TSESTree.Token | null; getNodeByRangeIndex(index: number): TSESTree.Node | null; - isSpaceBetweenTokens(first: AST.Token, second: AST.Token): boolean; + isSpaceBetweenTokens( + first: TSESTree.Token, + second: TSESTree.Token + ): boolean; getLocFromIndex(index: number): TSESTree.LineAndColumnData; @@ -96,103 +99,103 @@ declare module 'ts-eslint' { getTokenByRangeStart( offset: number, options?: { includeComments?: boolean } - ): AST.Token | null; + ): TSESTree.Token | null; getFirstToken( node: TSESTree.Node, options?: SourceCode.CursorWithSkipOptions - ): AST.Token | null; + ): TSESTree.Token | null; getFirstTokens( node: TSESTree.Node, options?: SourceCode.CursorWithCountOptions - ): AST.Token[]; + ): TSESTree.Token[]; getLastToken( node: TSESTree.Node, options?: SourceCode.CursorWithSkipOptions - ): AST.Token | null; + ): TSESTree.Token | null; getLastTokens( node: TSESTree.Node, options?: SourceCode.CursorWithCountOptions - ): AST.Token[]; + ): TSESTree.Token[]; getTokenBefore( - node: TSESTree.Node | AST.Token | TSESTree.Comment, + node: TSESTree.Node | TSESTree.Token | TSESTree.Comment, options?: SourceCode.CursorWithSkipOptions - ): AST.Token | null; + ): TSESTree.Token | null; getTokensBefore( - node: TSESTree.Node | AST.Token | TSESTree.Comment, + node: TSESTree.Node | TSESTree.Token | TSESTree.Comment, options?: SourceCode.CursorWithCountOptions - ): AST.Token[]; + ): TSESTree.Token[]; getTokenAfter( - node: TSESTree.Node | AST.Token | TSESTree.Comment, + node: TSESTree.Node | TSESTree.Token | TSESTree.Comment, options?: SourceCode.CursorWithSkipOptions - ): AST.Token | null; + ): TSESTree.Token | null; getTokensAfter( - node: TSESTree.Node | AST.Token | TSESTree.Comment, + node: TSESTree.Node | TSESTree.Token | TSESTree.Comment, options?: SourceCode.CursorWithCountOptions - ): AST.Token[]; + ): TSESTree.Token[]; getFirstTokenBetween( - left: TSESTree.Node | AST.Token | TSESTree.Comment, - right: TSESTree.Node | AST.Token | TSESTree.Comment, + left: TSESTree.Node | TSESTree.Token | TSESTree.Comment, + right: TSESTree.Node | TSESTree.Token | TSESTree.Comment, options?: SourceCode.CursorWithSkipOptions - ): AST.Token | null; + ): TSESTree.Token | null; getFirstTokensBetween( - left: TSESTree.Node | AST.Token | TSESTree.Comment, - right: TSESTree.Node | AST.Token | TSESTree.Comment, + left: TSESTree.Node | TSESTree.Token | TSESTree.Comment, + right: TSESTree.Node | TSESTree.Token | TSESTree.Comment, options?: SourceCode.CursorWithCountOptions - ): AST.Token[]; + ): TSESTree.Token[]; getLastTokenBetween( - left: TSESTree.Node | AST.Token | TSESTree.Comment, - right: TSESTree.Node | AST.Token | TSESTree.Comment, + left: TSESTree.Node | TSESTree.Token | TSESTree.Comment, + right: TSESTree.Node | TSESTree.Token | TSESTree.Comment, options?: SourceCode.CursorWithSkipOptions - ): AST.Token | null; + ): TSESTree.Token | null; getLastTokensBetween( - left: TSESTree.Node | AST.Token | TSESTree.Comment, - right: TSESTree.Node | AST.Token | TSESTree.Comment, + left: TSESTree.Node | TSESTree.Token | TSESTree.Comment, + right: TSESTree.Node | TSESTree.Token | TSESTree.Comment, options?: SourceCode.CursorWithCountOptions - ): AST.Token[]; + ): TSESTree.Token[]; getTokensBetween( - left: TSESTree.Node | AST.Token | TSESTree.Comment, - right: TSESTree.Node | AST.Token | TSESTree.Comment, + left: TSESTree.Node | TSESTree.Token | TSESTree.Comment, + right: TSESTree.Node | TSESTree.Token | TSESTree.Comment, padding?: | number | SourceCode.FilterPredicate | SourceCode.CursorWithCountOptions - ): AST.Token[]; + ): TSESTree.Token[]; getTokens( node: TSESTree.Node, beforeCount?: number, afterCount?: number - ): AST.Token[]; + ): TSESTree.Token[]; // eslint-disable-next-line no-dupe-class-members getTokens( node: TSESTree.Node, options: SourceCode.FilterPredicate | SourceCode.CursorWithCountOptions - ): AST.Token[]; + ): TSESTree.Token[]; commentsExistBetween( - left: TSESTree.Node | AST.Token, - right: TSESTree.Node | AST.Token + left: TSESTree.Node | TSESTree.Token, + right: TSESTree.Node | TSESTree.Token ): boolean; getCommentsBefore( - nodeOrToken: TSESTree.Node | AST.Token + nodeOrToken: TSESTree.Node | TSESTree.Token ): TSESTree.Comment[]; getCommentsAfter( - nodeOrToken: TSESTree.Node | AST.Token + nodeOrToken: TSESTree.Node | TSESTree.Token ): TSESTree.Comment[]; getCommentsInside(node: TSESTree.Node): TSESTree.Comment[]; @@ -269,24 +272,27 @@ declare module 'ts-eslint' { interface RuleFixer { insertTextAfter( - nodeOrToken: TSESTree.Node | AST.Token, + nodeOrToken: TSESTree.Node | TSESTree.Token, text: string ): RuleFix; insertTextAfterRange(range: AST.Range, text: string): RuleFix; insertTextBefore( - nodeOrToken: TSESTree.Node | AST.Token, + nodeOrToken: TSESTree.Node | TSESTree.Token, text: string ): RuleFix; insertTextBeforeRange(range: AST.Range, text: string): RuleFix; - remove(nodeOrToken: TSESTree.Node | AST.Token): RuleFix; + remove(nodeOrToken: TSESTree.Node | TSESTree.Token): RuleFix; removeRange(range: AST.Range): RuleFix; - replaceText(nodeOrToken: TSESTree.Node | AST.Token, text: string): RuleFix; + replaceText( + nodeOrToken: TSESTree.Node | TSESTree.Token, + text: string + ): RuleFix; replaceTextRange(range: AST.Range, text: string): RuleFix; } @@ -309,7 +315,7 @@ declare module 'ts-eslint' { /** * The Node or AST Token which the report is being attached to */ - node: TSESTree.Node | TSESTree.Comment | AST.Token; + node: TSESTree.Node | TSESTree.Comment | TSESTree.Token; /** * An override of the location of the report */ From ca5836e6b413ca5e16541d0729f86752864e10b6 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Wed, 6 Feb 2019 17:11:01 -0800 Subject: [PATCH 83/92] disable most eslint-plugin-eslint-plugin rules as they no longer are needed --- .eslintrc.json | 19 +++---------------- .../eslint-plugin/src/rules/array-type.ts | 8 ++++++-- .../src/rules/prefer-namespace-keyword.ts | 8 ++++++-- packages/eslint-plugin/src/util/createRule.ts | 1 + packages/typescript-estree/src/parser.ts | 2 +- 5 files changed, 17 insertions(+), 21 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 40a5182652ad..ce78adc0b641 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -30,7 +30,7 @@ { "files": [ "packages/eslint-plugin-tslint/tests/**/*.ts", - "packages/eslint-plugin/tests/**/*.js", + "packages/eslint-plugin/tests/**/*.test.ts", "packages/parser/tests/**/*.ts", "packages/typescript-estree/tests/**/*.ts" ], @@ -53,22 +53,9 @@ } }, { - "files": ["packages/eslint-plugin/**/*.js"], + "files": ["packages/eslint-plugin/test/**/*.ts"], "rules": { - "eslint-plugin/fixer-return": "error", - "eslint-plugin/no-identical-tests": "error", - "eslint-plugin/no-missing-placeholders": "error", - "eslint-plugin/no-unused-placeholders": "error", - "eslint-plugin/no-useless-token-range": "error", - "eslint-plugin/require-meta-fixable": "error", - "eslint-plugin/prefer-placeholders": "error", - "eslint-plugin/prefer-replace-text": "error", - "eslint-plugin/no-deprecated-report-api": "error", - "eslint-plugin/report-message-format": ["error", "^[A-Z'{].*[\\.}]$"], - "eslint-plugin/no-deprecated-context-methods": "error", - "eslint-plugin/prefer-output-null": "error", - "eslint-plugin/test-case-shorthand-strings": "error", - "eslint-plugin/require-meta-type": "error" + "eslint-plugin/no-identical-tests": "error" } } ] diff --git a/packages/eslint-plugin/src/rules/array-type.ts b/packages/eslint-plugin/src/rules/array-type.ts index 4baf51fb4aac..39b3715c47c1 100644 --- a/packages/eslint-plugin/src/rules/array-type.ts +++ b/packages/eslint-plugin/src/rules/array-type.ts @@ -4,7 +4,11 @@ * @author Armano */ -import { TSESTree, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; +import { + AST_NODE_TYPES, + AST_TOKEN_TYPES, + TSESTree +} from '@typescript-eslint/typescript-estree'; import * as util from '../util'; /** @@ -124,7 +128,7 @@ export default util.createRule({ return false; } - return prevToken.type === AST_NODE_TYPES.Identifier; + return prevToken.type === AST_TOKEN_TYPES.Identifier; } /** diff --git a/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts b/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts index 1ab088fa1121..83b668a1b8da 100644 --- a/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts +++ b/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts @@ -4,7 +4,11 @@ * @author Armano */ -import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/typescript-estree'; +import { + AST_NODE_TYPES, + AST_TOKEN_TYPES, + TSESTree +} from '@typescript-eslint/typescript-estree'; import * as util from '../util'; export default util.createRule({ @@ -40,7 +44,7 @@ export default util.createRule({ if ( moduleType && - moduleType.type === AST_NODE_TYPES.Identifier && + moduleType.type === AST_TOKEN_TYPES.Identifier && moduleType.value === 'module' ) { context.report({ diff --git a/packages/eslint-plugin/src/util/createRule.ts b/packages/eslint-plugin/src/util/createRule.ts index 4b7268cf7adf..7c21f629cf62 100644 --- a/packages/eslint-plugin/src/util/createRule.ts +++ b/packages/eslint-plugin/src/util/createRule.ts @@ -24,6 +24,7 @@ type CreateRuleMeta = { } & RemoveProps, 'docs'>; // This function will get much easier to call when this is merged https://github.com/Microsoft/TypeScript/pull/26349 +// TODO - when the above rule lands; add type checking for the context.report `data` property export function createRule< TOptions extends Readonly, TMessageIds extends string, diff --git a/packages/typescript-estree/src/parser.ts b/packages/typescript-estree/src/parser.ts index 3611e8743ebc..eaa5068780a2 100644 --- a/packages/typescript-estree/src/parser.ts +++ b/packages/typescript-estree/src/parser.ts @@ -418,6 +418,6 @@ export function parseAndGenerateServices< }; } -export { AST_NODE_TYPES } from './ast-node-types'; +export { AST_NODE_TYPES, AST_TOKEN_TYPES } from './ast-node-types'; export { ParserOptions }; export { TSESTree }; From 79fe2b7a85c00ecc0385e16bcfb7474f5dfd5fdb Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Wed, 6 Feb 2019 17:51:15 -0800 Subject: [PATCH 84/92] duplicated logic in no-extraneous-class --- .../eslint-plugin/src/rules/no-extraneous-class.ts | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-extraneous-class.ts b/packages/eslint-plugin/src/rules/no-extraneous-class.ts index 2b3aa0a54ee2..cb6c58de86c4 100644 --- a/packages/eslint-plugin/src/rules/no-extraneous-class.ts +++ b/packages/eslint-plugin/src/rules/no-extraneous-class.ts @@ -56,17 +56,6 @@ export default util.createRule({ } ], create(context, [{ allowConstructorOnly, allowEmpty, allowStaticOnly }]) { - function getReportNode(node: TSESTree.ClassBody): TSESTree.Node { - if (!node.parent) { - return node; - } - if ('id' in node.parent && node.parent.id) { - return node.parent.id; - } - - return node.parent; - } - return { ClassBody(node: TSESTree.ClassBody) { const parent = node.parent as @@ -78,7 +67,7 @@ export default util.createRule({ return; } - const reportNode = getReportNode(node); + const reportNode = 'id' in parent && parent.id ? parent.id : parent; if (node.body.length === 0) { if (allowEmpty) { From 5f6c1ed1ff6e7659e59353525264443dc261bc57 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Thu, 7 Feb 2019 11:49:37 -0800 Subject: [PATCH 85/92] fix types on promise-function-async --- .../eslint-plugin/src/rules/promise-function-async.ts | 8 +------- packages/eslint-plugin/typings/ts-eslint.d.ts | 4 +++- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/eslint-plugin/src/rules/promise-function-async.ts b/packages/eslint-plugin/src/rules/promise-function-async.ts index d6713d31c556..e2e65cfd1b6e 100644 --- a/packages/eslint-plugin/src/rules/promise-function-async.ts +++ b/packages/eslint-plugin/src/rules/promise-function-async.ts @@ -90,12 +90,7 @@ export default util.createRule({ const parserServices = util.getParserServices(context); const checker = parserServices.program.getTypeChecker(); - function validateNode( - node: - | TSESTree.ArrowFunctionExpression - | TSESTree.FunctionDeclaration - | TSESTree.FunctionExpression - ) { + function validateNode(node: TSESTree.Node) { const originalNode = parserServices.esTreeNodeToTSNodeMap.get(node); const [callSignature] = checker .getTypeAtLocation(originalNode) @@ -132,7 +127,6 @@ export default util.createRule({ node.parent.kind === 'method' ) { if (checkMethodDeclarations) { - // @ts-ignore validateNode(node.parent); } } else if (checkFunctionExpressions) { diff --git a/packages/eslint-plugin/typings/ts-eslint.d.ts b/packages/eslint-plugin/typings/ts-eslint.d.ts index f12cdf6339b4..9ab6ff35e213 100644 --- a/packages/eslint-plugin/typings/ts-eslint.d.ts +++ b/packages/eslint-plugin/typings/ts-eslint.d.ts @@ -397,7 +397,8 @@ declare module 'ts-eslint' { // This isn't the correct signature, but it makes it easier to do custom unions within reusable listneers // never will break someone's code unless they specifically type the function argument - type RuleListener = Record void>; + type RuleFunction = (node: never) => void; + type RuleListener = Record; interface RuleModule< TMessageIds extends string, @@ -525,6 +526,7 @@ declare module 'ts-eslint' { ReportFixFunction, RuleContext, RuleFix, + RuleFunction, RuleListener, RuleMetaData, RuleMetaDataDocs, From 2f6ff839142052523478e4a5d52a4e5ff5344e94 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Fri, 8 Feb 2019 17:59:46 -0800 Subject: [PATCH 86/92] rename the base tsconfig file to prevent errors in visual studio (not code) --- packages/eslint-plugin-tslint/tsconfig.build.json | 2 +- packages/eslint-plugin/tsconfig.build.json | 2 +- packages/parser/tsconfig.build.json | 2 +- packages/typescript-estree/tsconfig.build.json | 2 +- tsconfig.json => tsconfig.base.json | 0 5 files changed, 4 insertions(+), 4 deletions(-) rename tsconfig.json => tsconfig.base.json (100%) diff --git a/packages/eslint-plugin-tslint/tsconfig.build.json b/packages/eslint-plugin-tslint/tsconfig.build.json index b1224f98e68b..b0fced27d72d 100644 --- a/packages/eslint-plugin-tslint/tsconfig.build.json +++ b/packages/eslint-plugin-tslint/tsconfig.build.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.json", + "extends": "../../tsconfig.base.json", "compilerOptions": { "outDir": "./dist" }, diff --git a/packages/eslint-plugin/tsconfig.build.json b/packages/eslint-plugin/tsconfig.build.json index 304db267ae6e..1ab98da19abf 100644 --- a/packages/eslint-plugin/tsconfig.build.json +++ b/packages/eslint-plugin/tsconfig.build.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.json", + "extends": "../../tsconfig.base.json", "compilerOptions": { // specifically disable declarations for the plugin "declaration": false, diff --git a/packages/parser/tsconfig.build.json b/packages/parser/tsconfig.build.json index 8b51ca27bda3..578d82308403 100644 --- a/packages/parser/tsconfig.build.json +++ b/packages/parser/tsconfig.build.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.json", + "extends": "../../tsconfig.base.json", "compilerOptions": { "declaration": true, "outDir": "./dist" diff --git a/packages/typescript-estree/tsconfig.build.json b/packages/typescript-estree/tsconfig.build.json index b1224f98e68b..b0fced27d72d 100644 --- a/packages/typescript-estree/tsconfig.build.json +++ b/packages/typescript-estree/tsconfig.build.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.json", + "extends": "../../tsconfig.base.json", "compilerOptions": { "outDir": "./dist" }, diff --git a/tsconfig.json b/tsconfig.base.json similarity index 100% rename from tsconfig.json rename to tsconfig.base.json From 917a9f177c52bb0c1986fbce0e90346f94479631 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Sun, 10 Feb 2019 09:47:47 -0800 Subject: [PATCH 87/92] fix build --- packages/parser/tests/lib/parser.ts | 28 ++++--------------- .../tests/lib/semanticInfo.ts | 2 +- 2 files changed, 7 insertions(+), 23 deletions(-) diff --git a/packages/parser/tests/lib/parser.ts b/packages/parser/tests/lib/parser.ts index 6a844baae22e..46aa13dcbbf3 100644 --- a/packages/parser/tests/lib/parser.ts +++ b/packages/parser/tests/lib/parser.ts @@ -33,12 +33,12 @@ describe('parser', () => { it('parseAndGenerateServices() should be called with options', () => { const code = 'const valid = true;'; const spy = jest.spyOn(typescriptESTree, 'parseAndGenerateServices'); - parseForESLint(code, { + const config = { loc: false, comment: false, range: false, tokens: false, - sourceType: 'module', + sourceType: 'module' as 'module', ecmaVersion: 10, ecmaFeatures: { globalReturn: false, @@ -50,29 +50,13 @@ describe('parser', () => { useJSXTextNode: false, errorOnUnknownASTType: false, errorOnTypeScriptSyntacticAndSemanticIssues: false, - tsconfigRootDir: '../../', + tsconfigRootDir: './', extraFileExtensions: ['foo'] - }); + }; + parseForESLint(code, config); expect(spy).toHaveBeenCalledWith(code, { jsx: false, - loc: false, - comment: false, - range: false, - tokens: false, - sourceType: 'module', - ecmaVersion: 10, - ecmaFeatures: { - globalReturn: false, - jsx: false - }, - // ts-estree specific - filePath: 'test/foo', - project: 'tsconfig.json', - useJSXTextNode: false, - errorOnUnknownASTType: false, - errorOnTypeScriptSyntacticAndSemanticIssues: false, - tsconfigRootDir: '../../', - extraFileExtensions: ['foo'] + ...config }); }); diff --git a/packages/typescript-estree/tests/lib/semanticInfo.ts b/packages/typescript-estree/tests/lib/semanticInfo.ts index 126ad35879b6..d6286125f55f 100644 --- a/packages/typescript-estree/tests/lib/semanticInfo.ts +++ b/packages/typescript-estree/tests/lib/semanticInfo.ts @@ -22,7 +22,7 @@ import { VariableDeclaration, ClassDeclaration, ClassProperty -} from '../../src/typedefs'; +} from '../../src/ts-estree'; //------------------------------------------------------------------------------ // Setup From cb359d30e50f772b00e9b206369547a3add25529 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Sun, 10 Feb 2019 10:23:59 -0800 Subject: [PATCH 88/92] review --- packages/parser/src/analyze-scope.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/parser/src/analyze-scope.ts b/packages/parser/src/analyze-scope.ts index f3a6b5f78ac1..b6446af8de16 100644 --- a/packages/parser/src/analyze-scope.ts +++ b/packages/parser/src/analyze-scope.ts @@ -361,7 +361,9 @@ class Referencer extends OriginalReferencer { * Create reference objects for the references in parameters and return type. * @param node The TSEmptyBodyFunctionExpression node to visit. */ - TSEmptyBodyFunctionExpression(node: TSESTree.FunctionExpression): void { + TSEmptyBodyFunctionExpression( + node: TSESTree.TSEmptyBodyFunctionExpression + ): void { const upperTypeMode = this.typeMode; const { typeParameters, params, returnType } = node; From c652486160ab9437f930a3f9ade29c0770b1e396 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Sun, 10 Feb 2019 11:25:10 -0800 Subject: [PATCH 89/92] switch RuleTester to a non-default export --- packages/eslint-plugin/tests/RuleTester.ts | 6 +++--- .../eslint-plugin/tests/eslint-rules/arrow-parens.test.ts | 2 +- .../eslint-plugin/tests/eslint-rules/no-dupe-args.test.ts | 2 +- .../tests/eslint-rules/no-implicit-globals.test.ts | 2 +- .../eslint-plugin/tests/eslint-rules/no-redeclare.test.ts | 2 +- .../tests/eslint-rules/no-restricted-globals.test.ts | 2 +- packages/eslint-plugin/tests/eslint-rules/no-shadow.test.ts | 2 +- packages/eslint-plugin/tests/eslint-rules/no-undef.test.ts | 2 +- .../eslint-plugin/tests/eslint-rules/no-unused-vars.test.ts | 2 +- .../tests/eslint-rules/no-use-before-define.test.ts | 2 +- packages/eslint-plugin/tests/eslint-rules/strict.test.ts | 2 +- .../tests/rules/adjacent-overload-signatures.test.ts | 2 +- packages/eslint-plugin/tests/rules/array-type.test.ts | 2 +- packages/eslint-plugin/tests/rules/ban-types.test.ts | 2 +- packages/eslint-plugin/tests/rules/camelcase.test.ts | 2 +- .../eslint-plugin/tests/rules/class-name-casing.test.ts | 2 +- .../tests/rules/explicit-function-return-type.test.ts | 2 +- .../tests/rules/explicit-member-accessibility.test.ts | 2 +- .../eslint-plugin/tests/rules/generic-type-naming.test.ts | 2 +- packages/eslint-plugin/tests/rules/indent.test.ts | 2 +- .../eslint-plugin/tests/rules/interface-name-prefix.test.ts | 2 +- .../tests/rules/member-delimiter-style.test.ts | 2 +- packages/eslint-plugin/tests/rules/member-naming.test.ts | 2 +- packages/eslint-plugin/tests/rules/member-ordering.test.ts | 2 +- .../tests/rules/no-angle-bracket-type-assertion.test.ts | 2 +- .../eslint-plugin/tests/rules/no-array-constructor.test.ts | 2 +- .../eslint-plugin/tests/rules/no-empty-interface.test.ts | 2 +- packages/eslint-plugin/tests/rules/no-explicit-any.test.ts | 2 +- .../eslint-plugin/tests/rules/no-extraneous-class.test.ts | 2 +- packages/eslint-plugin/tests/rules/no-for-in-array.test.ts | 2 +- .../eslint-plugin/tests/rules/no-inferrable-types.test.ts | 2 +- packages/eslint-plugin/tests/rules/no-misused-new.test.ts | 2 +- packages/eslint-plugin/tests/rules/no-namespace.test.ts | 2 +- .../eslint-plugin/tests/rules/no-non-null-assertion.test.ts | 2 +- .../tests/rules/no-object-literal-type-assertion.test.ts | 2 +- .../tests/rules/no-parameter-properties.test.ts | 2 +- .../eslint-plugin/tests/rules/no-require-imports.test.ts | 2 +- packages/eslint-plugin/tests/rules/no-this-alias.test.ts | 2 +- .../tests/rules/no-triple-slash-reference.test.ts | 2 +- packages/eslint-plugin/tests/rules/no-type-alias.test.ts | 2 +- .../tests/rules/no-unnecessary-type-assertion.test.ts | 2 +- packages/eslint-plugin/tests/rules/no-unused-vars.test.ts | 2 +- .../eslint-plugin/tests/rules/no-use-before-define.test.ts | 2 +- .../tests/rules/no-useless-constructor.test.ts | 2 +- packages/eslint-plugin/tests/rules/no-var-requires.test.ts | 2 +- .../eslint-plugin/tests/rules/prefer-function-type.test.ts | 2 +- packages/eslint-plugin/tests/rules/prefer-interface.test.ts | 2 +- .../tests/rules/prefer-namespace-keyword.test.ts | 2 +- .../tests/rules/promise-function-async.test.ts | 2 +- .../tests/rules/restrict-plus-operands.test.ts | 2 +- .../tests/rules/type-annotation-spacing.test.ts | 2 +- 51 files changed, 53 insertions(+), 53 deletions(-) diff --git a/packages/eslint-plugin/tests/RuleTester.ts b/packages/eslint-plugin/tests/RuleTester.ts index e03a7535a9fd..1a553f1d3dd0 100644 --- a/packages/eslint-plugin/tests/RuleTester.ts +++ b/packages/eslint-plugin/tests/RuleTester.ts @@ -1,6 +1,6 @@ import { ParserOptions } from '@typescript-eslint/parser'; import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; -import { RuleTester } from 'eslint'; +import { RuleTester as ESLintRuleTester } from 'eslint'; import * as path from 'path'; import RuleModule from 'ts-eslint'; @@ -49,7 +49,7 @@ declare class RuleTesterTyped { ): void; } -const RuleTesterRetyped = (RuleTester as any) as { +const RuleTester = (ESLintRuleTester as any) as { new (config?: { parser: '@typescript-eslint/parser'; parserOptions?: ParserOptions; @@ -60,8 +60,8 @@ function getFixturesRootDir() { return path.join(process.cwd(), 'tests/fixtures/'); } -export default RuleTesterRetyped; export { + RuleTester, RunTests, TestCaseError, InvalidTestCase, diff --git a/packages/eslint-plugin/tests/eslint-rules/arrow-parens.test.ts b/packages/eslint-plugin/tests/eslint-rules/arrow-parens.test.ts index a8992a34ccf5..5e51e9e39066 100644 --- a/packages/eslint-plugin/tests/eslint-rules/arrow-parens.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/arrow-parens.test.ts @@ -1,5 +1,5 @@ import rule from 'eslint/lib/rules/arrow-parens'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/eslint-rules/no-dupe-args.test.ts b/packages/eslint-plugin/tests/eslint-rules/no-dupe-args.test.ts index 0c227678a877..4d9e8d3c9a68 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-dupe-args.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-dupe-args.test.ts @@ -1,5 +1,5 @@ import rule from 'eslint/lib/rules/no-dupe-args'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/eslint-rules/no-implicit-globals.test.ts b/packages/eslint-plugin/tests/eslint-rules/no-implicit-globals.test.ts index 98eb8bc0b661..b5f1616e265e 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-implicit-globals.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-implicit-globals.test.ts @@ -1,5 +1,5 @@ import rule from 'eslint/lib/rules/no-implicit-globals'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/eslint-rules/no-redeclare.test.ts b/packages/eslint-plugin/tests/eslint-rules/no-redeclare.test.ts index 35a84a4767db..51b56f72f6f2 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-redeclare.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-redeclare.test.ts @@ -1,5 +1,5 @@ import rule from 'eslint/lib/rules/no-redeclare'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.test.ts b/packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.test.ts index 18020fff8e32..a664a3bce20e 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.test.ts @@ -1,5 +1,5 @@ import rule from 'eslint/lib/rules/no-restricted-globals'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/eslint-rules/no-shadow.test.ts b/packages/eslint-plugin/tests/eslint-rules/no-shadow.test.ts index aa4628db6993..78580e7296d9 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-shadow.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-shadow.test.ts @@ -1,5 +1,5 @@ import rule from 'eslint/lib/rules/no-shadow'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/eslint-rules/no-undef.test.ts b/packages/eslint-plugin/tests/eslint-rules/no-undef.test.ts index a245c87bf0e3..700cb1522df1 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-undef.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-undef.test.ts @@ -1,5 +1,5 @@ import rule from 'eslint/lib/rules/no-undef'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/eslint-rules/no-unused-vars.test.ts b/packages/eslint-plugin/tests/eslint-rules/no-unused-vars.test.ts index dd5436d48d3b..ffa062ddd4f4 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-unused-vars.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-unused-vars.test.ts @@ -1,5 +1,5 @@ import rule from 'eslint/lib/rules/no-unused-vars'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/eslint-rules/no-use-before-define.test.ts b/packages/eslint-plugin/tests/eslint-rules/no-use-before-define.test.ts index e99e3f4db8ea..8c8e33533823 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-use-before-define.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-use-before-define.test.ts @@ -1,5 +1,5 @@ import rule from 'eslint/lib/rules/no-use-before-define'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/eslint-rules/strict.test.ts b/packages/eslint-plugin/tests/eslint-rules/strict.test.ts index 48299fdfdf86..76e3c22e5b75 100644 --- a/packages/eslint-plugin/tests/eslint-rules/strict.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/strict.test.ts @@ -1,5 +1,5 @@ import rule from 'eslint/lib/rules/strict'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.test.ts b/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.test.ts index b25da2c158a3..f0bc94f40a23 100644 --- a/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.test.ts +++ b/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/adjacent-overload-signatures'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/rules/array-type.test.ts b/packages/eslint-plugin/tests/rules/array-type.test.ts index fdb7976fae20..042d1613a1eb 100644 --- a/packages/eslint-plugin/tests/rules/array-type.test.ts +++ b/packages/eslint-plugin/tests/rules/array-type.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/array-type'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; import { Linter } from 'eslint'; const ruleTester = new RuleTester({ diff --git a/packages/eslint-plugin/tests/rules/ban-types.test.ts b/packages/eslint-plugin/tests/rules/ban-types.test.ts index e9cc6afe8e07..7f09a379f9ed 100644 --- a/packages/eslint-plugin/tests/rules/ban-types.test.ts +++ b/packages/eslint-plugin/tests/rules/ban-types.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/ban-types'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; import { InferOptionsTypeFromRule } from '../../src/util'; const ruleTester = new RuleTester({ diff --git a/packages/eslint-plugin/tests/rules/camelcase.test.ts b/packages/eslint-plugin/tests/rules/camelcase.test.ts index 292982f9c40e..64da778f7079 100644 --- a/packages/eslint-plugin/tests/rules/camelcase.test.ts +++ b/packages/eslint-plugin/tests/rules/camelcase.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/camelcase'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/rules/class-name-casing.test.ts b/packages/eslint-plugin/tests/rules/class-name-casing.test.ts index 2b9f1305e719..91713477338b 100644 --- a/packages/eslint-plugin/tests/rules/class-name-casing.test.ts +++ b/packages/eslint-plugin/tests/rules/class-name-casing.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/class-name-casing'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts b/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts index 1671f2773394..3348942e4d06 100644 --- a/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts +++ b/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/explicit-function-return-type'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts b/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts index d8578c533e6f..126a965ee54d 100644 --- a/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts +++ b/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/explicit-member-accessibility'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/rules/generic-type-naming.test.ts b/packages/eslint-plugin/tests/rules/generic-type-naming.test.ts index 06ff1ed904e8..125d22b56ffd 100644 --- a/packages/eslint-plugin/tests/rules/generic-type-naming.test.ts +++ b/packages/eslint-plugin/tests/rules/generic-type-naming.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/generic-type-naming'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/rules/indent.test.ts b/packages/eslint-plugin/tests/rules/indent.test.ts index f955e3aef7a8..10299325659b 100644 --- a/packages/eslint-plugin/tests/rules/indent.test.ts +++ b/packages/eslint-plugin/tests/rules/indent.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/indent'; -import RuleTester, { RunTests, TestCaseError } from '../RuleTester'; +import { RuleTester, RunTests, TestCaseError } from '../RuleTester'; import { InferMessageIdsTypeFromRule, InferOptionsTypeFromRule diff --git a/packages/eslint-plugin/tests/rules/interface-name-prefix.test.ts b/packages/eslint-plugin/tests/rules/interface-name-prefix.test.ts index 7706ed842d60..919376676b7f 100644 --- a/packages/eslint-plugin/tests/rules/interface-name-prefix.test.ts +++ b/packages/eslint-plugin/tests/rules/interface-name-prefix.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/interface-name-prefix'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/rules/member-delimiter-style.test.ts b/packages/eslint-plugin/tests/rules/member-delimiter-style.test.ts index 80b2d152741c..e2e8562a4309 100644 --- a/packages/eslint-plugin/tests/rules/member-delimiter-style.test.ts +++ b/packages/eslint-plugin/tests/rules/member-delimiter-style.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/member-delimiter-style'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/rules/member-naming.test.ts b/packages/eslint-plugin/tests/rules/member-naming.test.ts index 46365b432ec3..95cf21f3c62d 100644 --- a/packages/eslint-plugin/tests/rules/member-naming.test.ts +++ b/packages/eslint-plugin/tests/rules/member-naming.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/member-naming'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/rules/member-ordering.test.ts b/packages/eslint-plugin/tests/rules/member-ordering.test.ts index 98170e07c749..29fb131d2a96 100644 --- a/packages/eslint-plugin/tests/rules/member-ordering.test.ts +++ b/packages/eslint-plugin/tests/rules/member-ordering.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/member-ordering'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/rules/no-angle-bracket-type-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-angle-bracket-type-assertion.test.ts index f978aaaa75ed..0a251d759823 100644 --- a/packages/eslint-plugin/tests/rules/no-angle-bracket-type-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-angle-bracket-type-assertion.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/no-angle-bracket-type-assertion'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/rules/no-array-constructor.test.ts b/packages/eslint-plugin/tests/rules/no-array-constructor.test.ts index 6efdd6ab041f..68253279316d 100644 --- a/packages/eslint-plugin/tests/rules/no-array-constructor.test.ts +++ b/packages/eslint-plugin/tests/rules/no-array-constructor.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/no-array-constructor'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts b/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts index ff7c1c5d6161..2410509a1fcd 100644 --- a/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts +++ b/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/no-empty-interface'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/rules/no-explicit-any.test.ts b/packages/eslint-plugin/tests/rules/no-explicit-any.test.ts index 7da776f07efa..50fc0f95fc32 100644 --- a/packages/eslint-plugin/tests/rules/no-explicit-any.test.ts +++ b/packages/eslint-plugin/tests/rules/no-explicit-any.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/no-explicit-any'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/rules/no-extraneous-class.test.ts b/packages/eslint-plugin/tests/rules/no-extraneous-class.test.ts index ffcd17cc8395..7704eba8c5af 100644 --- a/packages/eslint-plugin/tests/rules/no-extraneous-class.test.ts +++ b/packages/eslint-plugin/tests/rules/no-extraneous-class.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/no-extraneous-class'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const empty = { messageId: 'empty' as 'empty' diff --git a/packages/eslint-plugin/tests/rules/no-for-in-array.test.ts b/packages/eslint-plugin/tests/rules/no-for-in-array.test.ts index 1dd044b2897f..d9fd9497ce22 100644 --- a/packages/eslint-plugin/tests/rules/no-for-in-array.test.ts +++ b/packages/eslint-plugin/tests/rules/no-for-in-array.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/no-for-in-array'; -import RuleTester, { getFixturesRootDir } from '../RuleTester'; +import { RuleTester, getFixturesRootDir } from '../RuleTester'; const rootDir = getFixturesRootDir(); const ruleTester = new RuleTester({ diff --git a/packages/eslint-plugin/tests/rules/no-inferrable-types.test.ts b/packages/eslint-plugin/tests/rules/no-inferrable-types.test.ts index 0999c66a6e06..ab76c5ef0e34 100644 --- a/packages/eslint-plugin/tests/rules/no-inferrable-types.test.ts +++ b/packages/eslint-plugin/tests/rules/no-inferrable-types.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/no-inferrable-types'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/rules/no-misused-new.test.ts b/packages/eslint-plugin/tests/rules/no-misused-new.test.ts index 00d1d0f07f04..37a16cf406ad 100644 --- a/packages/eslint-plugin/tests/rules/no-misused-new.test.ts +++ b/packages/eslint-plugin/tests/rules/no-misused-new.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/no-misused-new'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/rules/no-namespace.test.ts b/packages/eslint-plugin/tests/rules/no-namespace.test.ts index 446060421086..8488dcc27b19 100644 --- a/packages/eslint-plugin/tests/rules/no-namespace.test.ts +++ b/packages/eslint-plugin/tests/rules/no-namespace.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/no-namespace'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts index d33c2a671f19..84e8ef695b91 100644 --- a/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/no-non-null-assertion'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/rules/no-object-literal-type-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-object-literal-type-assertion.test.ts index 83c577932542..23ced3296c62 100644 --- a/packages/eslint-plugin/tests/rules/no-object-literal-type-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-object-literal-type-assertion.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/no-object-literal-type-assertion'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-parameter-properties.test.ts b/packages/eslint-plugin/tests/rules/no-parameter-properties.test.ts index 033539a1acba..a4dc16689780 100644 --- a/packages/eslint-plugin/tests/rules/no-parameter-properties.test.ts +++ b/packages/eslint-plugin/tests/rules/no-parameter-properties.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/no-parameter-properties'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/rules/no-require-imports.test.ts b/packages/eslint-plugin/tests/rules/no-require-imports.test.ts index 7599fcd7d11e..8e8e310bd61d 100644 --- a/packages/eslint-plugin/tests/rules/no-require-imports.test.ts +++ b/packages/eslint-plugin/tests/rules/no-require-imports.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/no-require-imports'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/rules/no-this-alias.test.ts b/packages/eslint-plugin/tests/rules/no-this-alias.test.ts index 34150830c18c..25338a5158fa 100644 --- a/packages/eslint-plugin/tests/rules/no-this-alias.test.ts +++ b/packages/eslint-plugin/tests/rules/no-this-alias.test.ts @@ -1,6 +1,6 @@ import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; import rule from '../../src/rules/no-this-alias'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const idError = { messageId: 'thisAssignment' as 'thisAssignment', diff --git a/packages/eslint-plugin/tests/rules/no-triple-slash-reference.test.ts b/packages/eslint-plugin/tests/rules/no-triple-slash-reference.test.ts index 5b3860fd49fd..4fddd596aa5c 100644 --- a/packages/eslint-plugin/tests/rules/no-triple-slash-reference.test.ts +++ b/packages/eslint-plugin/tests/rules/no-triple-slash-reference.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/no-triple-slash-reference'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/rules/no-type-alias.test.ts b/packages/eslint-plugin/tests/rules/no-type-alias.test.ts index 6607e70a512f..29670540cc1e 100644 --- a/packages/eslint-plugin/tests/rules/no-type-alias.test.ts +++ b/packages/eslint-plugin/tests/rules/no-type-alias.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/no-type-alias'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts index cb83835ce603..e223fc4ac0e6 100644 --- a/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts @@ -1,6 +1,6 @@ import path from 'path'; import rule from '../../src/rules/no-unnecessary-type-assertion'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const rootDir = path.join(process.cwd(), 'tests/fixtures'); const parserOptions = { diff --git a/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts b/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts index 4d5a16e4da7e..2e188c870a06 100644 --- a/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/no-unused-vars'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts b/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts index 286b3115a20b..dc56199e5885 100644 --- a/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts +++ b/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/no-use-before-define'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; const ruleTester = new RuleTester({ diff --git a/packages/eslint-plugin/tests/rules/no-useless-constructor.test.ts b/packages/eslint-plugin/tests/rules/no-useless-constructor.test.ts index 05320c9962b7..631e8e23cc40 100644 --- a/packages/eslint-plugin/tests/rules/no-useless-constructor.test.ts +++ b/packages/eslint-plugin/tests/rules/no-useless-constructor.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/no-useless-constructor'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/rules/no-var-requires.test.ts b/packages/eslint-plugin/tests/rules/no-var-requires.test.ts index b7514271aa55..adcce58d9204 100644 --- a/packages/eslint-plugin/tests/rules/no-var-requires.test.ts +++ b/packages/eslint-plugin/tests/rules/no-var-requires.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/no-var-requires'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/rules/prefer-function-type.test.ts b/packages/eslint-plugin/tests/rules/prefer-function-type.test.ts index ca17ee023bff..376f687188a2 100644 --- a/packages/eslint-plugin/tests/rules/prefer-function-type.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-function-type.test.ts @@ -1,6 +1,6 @@ import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; import rule from '../../src/rules/prefer-function-type'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; var ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/rules/prefer-interface.test.ts b/packages/eslint-plugin/tests/rules/prefer-interface.test.ts index 05e08b04f61d..6519b92d3d2b 100644 --- a/packages/eslint-plugin/tests/rules/prefer-interface.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-interface.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/prefer-interface'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/rules/prefer-namespace-keyword.test.ts b/packages/eslint-plugin/tests/rules/prefer-namespace-keyword.test.ts index 847c09fc4f79..a68c19de2e3c 100644 --- a/packages/eslint-plugin/tests/rules/prefer-namespace-keyword.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-namespace-keyword.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/prefer-namespace-keyword'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser' diff --git a/packages/eslint-plugin/tests/rules/promise-function-async.test.ts b/packages/eslint-plugin/tests/rules/promise-function-async.test.ts index dbc6b13f8803..71f93d669bf3 100644 --- a/packages/eslint-plugin/tests/rules/promise-function-async.test.ts +++ b/packages/eslint-plugin/tests/rules/promise-function-async.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/promise-function-async'; -import RuleTester, { getFixturesRootDir } from '../RuleTester'; +import { RuleTester, getFixturesRootDir } from '../RuleTester'; const rootDir = getFixturesRootDir(); const parserOptions = { diff --git a/packages/eslint-plugin/tests/rules/restrict-plus-operands.test.ts b/packages/eslint-plugin/tests/rules/restrict-plus-operands.test.ts index 6c0be726602c..448508666188 100644 --- a/packages/eslint-plugin/tests/rules/restrict-plus-operands.test.ts +++ b/packages/eslint-plugin/tests/rules/restrict-plus-operands.test.ts @@ -1,6 +1,6 @@ import path from 'path'; import rule from '../../src/rules/restrict-plus-operands'; -import RuleTester from '../RuleTester'; +import { RuleTester } from '../RuleTester'; const rootPath = path.join(process.cwd(), 'tests/fixtures/'); diff --git a/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts index 2f4b43fda7c5..df0de30eaa08 100644 --- a/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts @@ -1,5 +1,5 @@ import rule from '../../src/rules/type-annotation-spacing'; -import RuleTester, { InvalidTestCase, ValidTestCase } from '../RuleTester'; +import { RuleTester, InvalidTestCase, ValidTestCase } from '../RuleTester'; import { InferMessageIdsTypeFromRule, InferOptionsTypeFromRule From 51c7635dd302b91706efc1280c533b2926b81077 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Sun, 10 Feb 2019 11:32:20 -0800 Subject: [PATCH 90/92] review fixes pt 1 --- .../eslint-plugin/src/rules/explicit-function-return-type.ts | 2 +- .../eslint-plugin/src/rules/explicit-member-accessibility.ts | 4 ++-- packages/eslint-plugin/src/util/applyDefault.ts | 3 +-- packages/eslint-plugin/src/util/createRule.ts | 2 +- packages/eslint-plugin/src/util/misc.ts | 2 +- packages/eslint-plugin/tests/RuleTester.ts | 2 -- packages/eslint-plugin/tests/util.test.ts | 4 ++-- 7 files changed, 8 insertions(+), 11 deletions(-) diff --git a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts index 073c122b31db..0a7a0db73995 100644 --- a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts +++ b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts @@ -80,7 +80,7 @@ export default util.createRule({ node.parent && !isConstructor(node.parent) && !isSetter(node.parent) && - util.isTypescript(context.getFilename()) + util.isTypeScriptFile(context.getFilename()) ) { context.report({ node, diff --git a/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts index c81b6e7891a7..06a04b24e7ac 100644 --- a/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts +++ b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts @@ -34,7 +34,7 @@ export default util.createRule({ ): void { if ( !methodDefinition.accessibility && - util.isTypescript(context.getFilename()) + util.isTypeScriptFile(context.getFilename()) ) { context.report({ node: methodDefinition, @@ -56,7 +56,7 @@ export default util.createRule({ ): void { if ( !classProperty.accessibility && - util.isTypescript(context.getFilename()) + util.isTypeScriptFile(context.getFilename()) ) { context.report({ node: classProperty, diff --git a/packages/eslint-plugin/src/util/applyDefault.ts b/packages/eslint-plugin/src/util/applyDefault.ts index 297792dd834c..37a399ad68ea 100644 --- a/packages/eslint-plugin/src/util/applyDefault.ts +++ b/packages/eslint-plugin/src/util/applyDefault.ts @@ -14,8 +14,7 @@ export function applyDefault( // clone defaults const options: TDefault = JSON.parse(JSON.stringify(defaultOptions)); - // eslint-disable-next-line eqeqeq - if (userOptions == null) { + if (userOptions === null || userOptions === undefined) { return options; } diff --git a/packages/eslint-plugin/src/util/createRule.ts b/packages/eslint-plugin/src/util/createRule.ts index 7c21f629cf62..511c51c7e0c0 100644 --- a/packages/eslint-plugin/src/util/createRule.ts +++ b/packages/eslint-plugin/src/util/createRule.ts @@ -15,7 +15,7 @@ type RemoveProps< TKeys extends keyof TObj > = Pick>; -// we'll automatically +// we'll automatically add the url + tslint description for people. type CreateRuleMetaDocs = RemoveProps & { tslintName?: string; }; diff --git a/packages/eslint-plugin/src/util/misc.ts b/packages/eslint-plugin/src/util/misc.ts index ab3075c42c4d..483fb6a140ef 100644 --- a/packages/eslint-plugin/src/util/misc.ts +++ b/packages/eslint-plugin/src/util/misc.ts @@ -8,7 +8,7 @@ import RuleModule from 'ts-eslint'; /** * Check if the context file name is *.ts or *.tsx */ -export function isTypescript(fileName: string) { +export function isTypeScriptFile(fileName: string) { return /\.tsx?$/i.test(fileName || ''); } diff --git a/packages/eslint-plugin/tests/RuleTester.ts b/packages/eslint-plugin/tests/RuleTester.ts index 1a553f1d3dd0..20896e9d848b 100644 --- a/packages/eslint-plugin/tests/RuleTester.ts +++ b/packages/eslint-plugin/tests/RuleTester.ts @@ -28,8 +28,6 @@ interface TestCaseError { type?: AST_NODE_TYPES; line?: number; column?: number; - // endLine?: number; - // endColumn?: number; } interface RunTests< diff --git a/packages/eslint-plugin/tests/util.test.ts b/packages/eslint-plugin/tests/util.test.ts index 0fa29aec7a1f..b21f59a945a4 100644 --- a/packages/eslint-plugin/tests/util.test.ts +++ b/packages/eslint-plugin/tests/util.test.ts @@ -16,7 +16,7 @@ describe('isTypescript', () => { ]; invalid.forEach(f => { - assert.strictEqual(util.isTypescript(f), false); + assert.strictEqual(util.isTypeScriptFile(f), false); }); }); @@ -33,7 +33,7 @@ describe('isTypescript', () => { ]; valid.forEach(f => { - assert.strictEqual(util.isTypescript(f), true); + assert.strictEqual(util.isTypeScriptFile(f), true); }); }); }); From 5c8ad1a0617e63ca123b2881017bb4d64e2cd389 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Sun, 10 Feb 2019 11:45:48 -0800 Subject: [PATCH 91/92] add removed type checks back into tests --- .../tests/rules/no-array-constructor.test.ts | 57 ++++++++++++++++--- .../tests/rules/no-extraneous-class.test.ts | 8 ++- .../tests/rules/no-for-in-array.test.ts | 7 ++- 3 files changed, 61 insertions(+), 11 deletions(-) diff --git a/packages/eslint-plugin/tests/rules/no-array-constructor.test.ts b/packages/eslint-plugin/tests/rules/no-array-constructor.test.ts index 68253279316d..93e99cb618e9 100644 --- a/packages/eslint-plugin/tests/rules/no-array-constructor.test.ts +++ b/packages/eslint-plugin/tests/rules/no-array-constructor.test.ts @@ -1,3 +1,4 @@ +import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; import rule from '../../src/rules/no-array-constructor'; import { RuleTester } from '../RuleTester'; @@ -29,37 +30,72 @@ ruleTester.run('no-array-constructor', rule, { { code: 'new Array()', output: '[]', - errors: [{ messageId }] + errors: [ + { + messageId, + type: AST_NODE_TYPES.NewExpression + } + ] }, { code: 'Array()', output: '[]', - errors: [{ messageId }] + errors: [ + { + messageId, + type: AST_NODE_TYPES.CallExpression + } + ] }, { code: 'new Array', output: '[]', - errors: [{ messageId }] + errors: [ + { + messageId, + type: AST_NODE_TYPES.NewExpression + } + ] }, { code: 'new Array(x, y)', output: '[x, y]', - errors: [{ messageId }] + errors: [ + { + messageId, + type: AST_NODE_TYPES.NewExpression + } + ] }, { code: 'Array(x, y)', output: '[x, y]', - errors: [{ messageId }] + errors: [ + { + messageId, + type: AST_NODE_TYPES.CallExpression + } + ] }, { code: 'new Array(0, 1, 2)', output: '[0, 1, 2]', - errors: [{ messageId }] + errors: [ + { + messageId, + type: AST_NODE_TYPES.NewExpression + } + ] }, { code: 'Array(0, 1, 2)', output: '[0, 1, 2]', - errors: [{ messageId }] + errors: [ + { + messageId, + type: AST_NODE_TYPES.CallExpression + } + ] }, { code: `new Array( @@ -72,7 +108,12 @@ ruleTester.run('no-array-constructor', rule, { 1, 2 ]`, - errors: [{ messageId }] + errors: [ + { + messageId, + type: AST_NODE_TYPES.NewExpression + } + ] } ] }); diff --git a/packages/eslint-plugin/tests/rules/no-extraneous-class.test.ts b/packages/eslint-plugin/tests/rules/no-extraneous-class.test.ts index 7704eba8c5af..ded0672e9d4c 100644 --- a/packages/eslint-plugin/tests/rules/no-extraneous-class.test.ts +++ b/packages/eslint-plugin/tests/rules/no-extraneous-class.test.ts @@ -1,3 +1,4 @@ +import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; import rule from '../../src/rules/no-extraneous-class'; import { RuleTester } from '../RuleTester'; @@ -117,7 +118,12 @@ export class AClass { { // https://github.com/typescript-eslint/typescript-eslint/issues/170 code: 'export default class { static hello() {} }', - errors: [onlyStatic] + errors: [ + { + ...onlyStatic, + type: AST_NODE_TYPES.ClassDeclaration + } + ] } ] }); diff --git a/packages/eslint-plugin/tests/rules/no-for-in-array.test.ts b/packages/eslint-plugin/tests/rules/no-for-in-array.test.ts index d9fd9497ce22..d79ad4757c8e 100644 --- a/packages/eslint-plugin/tests/rules/no-for-in-array.test.ts +++ b/packages/eslint-plugin/tests/rules/no-for-in-array.test.ts @@ -1,3 +1,4 @@ +import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree'; import rule from '../../src/rules/no-for-in-array'; import { RuleTester, getFixturesRootDir } from '../RuleTester'; @@ -31,7 +32,8 @@ for (const x in [3, 4, 5]) { }`, errors: [ { - messageId: 'forInViolation' + messageId: 'forInViolation', + type: AST_NODE_TYPES.ForInStatement } ] }, @@ -43,7 +45,8 @@ for (const x in z) { }`, errors: [ { - messageId: 'forInViolation' + messageId: 'forInViolation', + type: AST_NODE_TYPES.ForInStatement } ] } From 3384ed124991e125f6440ab09e7275050ebbfb0e Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Sun, 10 Feb 2019 11:57:05 -0800 Subject: [PATCH 92/92] barrel up ts-estree --- packages/typescript-estree/src/convert-comments.ts | 2 +- packages/typescript-estree/src/convert.ts | 3 +-- packages/typescript-estree/src/node-utils.ts | 3 +-- packages/typescript-estree/src/parser-options.ts | 2 +- packages/typescript-estree/src/parser.ts | 6 +++--- .../typescript-estree/src/{ => ts-estree}/ast-node-types.ts | 0 packages/typescript-estree/src/ts-estree/index.ts | 5 +++++ packages/typescript-estree/src/{ => ts-estree}/ts-estree.ts | 0 packages/typescript-estree/tests/ast-alignment/utils.ts | 2 +- packages/typescript-estree/tests/lib/semanticInfo.ts | 2 +- 10 files changed, 14 insertions(+), 11 deletions(-) rename packages/typescript-estree/src/{ => ts-estree}/ast-node-types.ts (100%) create mode 100644 packages/typescript-estree/src/ts-estree/index.ts rename packages/typescript-estree/src/{ => ts-estree}/ts-estree.ts (100%) diff --git a/packages/typescript-estree/src/convert-comments.ts b/packages/typescript-estree/src/convert-comments.ts index 1dd419e4eb1c..1efff92648dc 100644 --- a/packages/typescript-estree/src/convert-comments.ts +++ b/packages/typescript-estree/src/convert-comments.ts @@ -7,7 +7,7 @@ import ts from 'typescript'; import { getLocFor, getNodeContainer } from './node-utils'; -import * as TSESTree from './ts-estree'; +import { TSESTree } from './ts-estree'; /** * Converts a TypeScript comment to an Esprima comment. diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index faa660e04423..38abe7f3272d 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -6,7 +6,6 @@ * MIT License */ import ts from 'typescript'; -import * as TSESTree from './ts-estree'; import { canContainDirective, createError, @@ -27,7 +26,7 @@ import { isOptional, unescapeStringLiteralText } from './node-utils'; -import { AST_NODE_TYPES } from './ast-node-types'; +import { AST_NODE_TYPES, TSESTree } from './ts-estree'; import { TSNode } from './ts-nodes'; const SyntaxKind = ts.SyntaxKind; diff --git a/packages/typescript-estree/src/node-utils.ts b/packages/typescript-estree/src/node-utils.ts index fdabb0931abf..8d0db4d74b3d 100644 --- a/packages/typescript-estree/src/node-utils.ts +++ b/packages/typescript-estree/src/node-utils.ts @@ -6,8 +6,7 @@ */ import ts from 'typescript'; import unescape from 'lodash.unescape'; -import * as TSESTree from './ts-estree'; -import { AST_NODE_TYPES, AST_TOKEN_TYPES } from './ast-node-types'; +import { AST_NODE_TYPES, AST_TOKEN_TYPES, TSESTree } from './ts-estree'; const SyntaxKind = ts.SyntaxKind; diff --git a/packages/typescript-estree/src/parser-options.ts b/packages/typescript-estree/src/parser-options.ts index db40eefc85a6..8a30b27b89ff 100644 --- a/packages/typescript-estree/src/parser-options.ts +++ b/packages/typescript-estree/src/parser-options.ts @@ -1,5 +1,5 @@ import { Program } from 'typescript'; -import { Token, Comment, Node } from './ts-estree'; +import { Token, Comment, Node } from './ts-estree/ts-estree'; import { TSNode } from './ts-nodes'; export interface Extra { diff --git a/packages/typescript-estree/src/parser.ts b/packages/typescript-estree/src/parser.ts index 87e46b9badbf..9edec09a35b5 100644 --- a/packages/typescript-estree/src/parser.ts +++ b/packages/typescript-estree/src/parser.ts @@ -14,7 +14,7 @@ import ts from 'typescript'; import convert from './ast-converter'; import { convertError } from './convert'; import { firstDefined } from './node-utils'; -import * as TSESTree from './ts-estree'; +import { TSESTree } from './ts-estree'; import { Extra, ParserOptions, ParserServices } from './parser-options'; import { getFirstSemanticOrSyntacticError } from './semantic-errors'; @@ -413,5 +413,5 @@ export function parseAndGenerateServices< }; } -export { AST_NODE_TYPES, AST_TOKEN_TYPES } from './ast-node-types'; -export { ParserOptions, ParserServices, TSESTree }; +export { AST_NODE_TYPES, AST_TOKEN_TYPES, TSESTree } from './ts-estree'; +export { ParserOptions, ParserServices }; diff --git a/packages/typescript-estree/src/ast-node-types.ts b/packages/typescript-estree/src/ts-estree/ast-node-types.ts similarity index 100% rename from packages/typescript-estree/src/ast-node-types.ts rename to packages/typescript-estree/src/ts-estree/ast-node-types.ts diff --git a/packages/typescript-estree/src/ts-estree/index.ts b/packages/typescript-estree/src/ts-estree/index.ts new file mode 100644 index 000000000000..4a6b74aef1fc --- /dev/null +++ b/packages/typescript-estree/src/ts-estree/index.ts @@ -0,0 +1,5 @@ +import * as TSESTree from './ts-estree'; + +export * from './ast-node-types'; +export * from '../ts-nodes'; +export { TSESTree }; diff --git a/packages/typescript-estree/src/ts-estree.ts b/packages/typescript-estree/src/ts-estree/ts-estree.ts similarity index 100% rename from packages/typescript-estree/src/ts-estree.ts rename to packages/typescript-estree/src/ts-estree/ts-estree.ts diff --git a/packages/typescript-estree/tests/ast-alignment/utils.ts b/packages/typescript-estree/tests/ast-alignment/utils.ts index 3b9cdfd087c9..8fcc90e1ffba 100644 --- a/packages/typescript-estree/tests/ast-alignment/utils.ts +++ b/packages/typescript-estree/tests/ast-alignment/utils.ts @@ -1,5 +1,5 @@ import isPlainObject from 'lodash.isplainobject'; -import { AST_NODE_TYPES } from '../../src/ast-node-types'; +import { AST_NODE_TYPES } from '../../src/ts-estree'; /** * By default, pretty-format (within Jest matchers) retains the names/types of nodes from the babylon AST, diff --git a/packages/typescript-estree/tests/lib/semanticInfo.ts b/packages/typescript-estree/tests/lib/semanticInfo.ts index d6286125f55f..7fb09b92dcb8 100644 --- a/packages/typescript-estree/tests/lib/semanticInfo.ts +++ b/packages/typescript-estree/tests/lib/semanticInfo.ts @@ -22,7 +22,7 @@ import { VariableDeclaration, ClassDeclaration, ClassProperty -} from '../../src/ts-estree'; +} from '../../src/ts-estree/ts-estree'; //------------------------------------------------------------------------------ // Setup