diff --git a/.github/workflows/manual-release.yml b/.github/workflows/manual-release.yml new file mode 100644 index 000000000000..4f75c3b438e7 --- /dev/null +++ b/.github/workflows/manual-release.yml @@ -0,0 +1,66 @@ +# This workflow is used on the rare occassion we need to manually cut a release. +# It can be triggered via the Github UI or the Github API. + +name: Manual publish to Github Releases and NPM + +on: + workflow_dispatch: + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + # Check out as an admin to allow for pushing back to master + token: ${{ secrets.JAMES_HENRY_GH_TOKEN }} + # Check out the branch that was specified as part of the trigger + ref: ${{ github.ref }} + # We need to fetch all tags and branches + fetch-depth: 0 + + - name: Verify head of master hasn't changed + run: | + # We ensure that the latest commit on master is still the one we expected when + # we started the release job, otherwise we exit + if [ "$GITHUB_SHA" != "$(git rev-parse --verify HEAD)" ]; then + echo "ERROR: The commit SHA at the HEAD of master has changed" + echo "Expected: $GITHUB_SHA" + echo "Actual: $(git rev-parse --verify HEAD)" + exit 1; + fi + + - name: Get yarn cache directory path + id: yarn-cache-dir-path + run: echo "::set-output name=dir::$(yarn cache dir)" + + - uses: actions/cache@v2 + id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) + with: + path: ${{ steps.yarn-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + + - name: Install dependencies + run: | + yarn --ignore-engines --frozen-lockfile --ignore-scripts + yarn lerna:init + yarn check:clean-workspace-after-install + + - name: Run build + run: | + yarn build + + - name: Determine what version to release and publish to Github (--yes skips the confirmation prompt) + run: | + # Required for github release to work + git config user.name 'James Henry' + git config user.email 'james@henry.sc' + + GH_TOKEN=${{ secrets.JAMES_HENRY_GH_TOKEN }} npx lerna version --loglevel=silly --yes --conventional-commits --exact --force-publish --github-release -m "chore: publish %s" + + - name: Publish the updated versions to NPM (--yes skips the confirmation prompt) + run: npx lerna publish from-package --yes + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 549fa2afd906..3766595afa8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,24 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.1.1](https://github.com/typescript-eslint/typescript-eslint/compare/v4.1.0...v4.1.1) (2020-09-14) + + +### Bug Fixes + +* **eslint-plugin:** [naming-convention] allow an array of selectors with types and modifiers ([#2415](https://github.com/typescript-eslint/typescript-eslint/issues/2415)) ([7ca54c3](https://github.com/typescript-eslint/typescript-eslint/commit/7ca54c3e4601ad07db5b882a67965cd67a18c4b3)) +* **eslint-plugin:** [no-implied-eval] handle the `Function` type ([#2435](https://github.com/typescript-eslint/typescript-eslint/issues/2435)) ([e1401dc](https://github.com/typescript-eslint/typescript-eslint/commit/e1401dc5897d01da516802cfb2333cf4bc6d0e93)) +* **eslint-plugin:** [no-unused-vars] better handling for declared modules ([#2553](https://github.com/typescript-eslint/typescript-eslint/issues/2553)) ([02d72d4](https://github.com/typescript-eslint/typescript-eslint/commit/02d72d480be7a8f7ddc66a028338cfb996886f3c)), closes [#2523](https://github.com/typescript-eslint/typescript-eslint/issues/2523) +* **eslint-plugin:** [no-use-before-define] false positive for function type arguments ([#2554](https://github.com/typescript-eslint/typescript-eslint/issues/2554)) ([189162d](https://github.com/typescript-eslint/typescript-eslint/commit/189162d46ecb116c420232937a7f86df913f4e79)), closes [#2527](https://github.com/typescript-eslint/typescript-eslint/issues/2527) +* **eslint-plugin:** [prefer-function-type] handle `this` return ([#2437](https://github.com/typescript-eslint/typescript-eslint/issues/2437)) ([7c6fcee](https://github.com/typescript-eslint/typescript-eslint/commit/7c6fcee657dffd041e389e0aeaa4f3e278e92986)) +* **eslint-plugin:** [return-await] don't error for `in-try-catch` if the return is in a `catch` without a `finally` ([#2356](https://github.com/typescript-eslint/typescript-eslint/issues/2356)) ([efdd521](https://github.com/typescript-eslint/typescript-eslint/commit/efdd5213ceaef332cf0b2c26573176f844d22a09)) +* **types:** artificial fix needed to trigger release ([b577daf](https://github.com/typescript-eslint/typescript-eslint/commit/b577daf27cd87870b6e095e4e995519f96d321dd)) +* **types:** artificial fix needed to trigger release ([fc62ba8](https://github.com/typescript-eslint/typescript-eslint/commit/fc62ba8622ed634e4c2d8399a4e880f983747181)) + + + + + # [4.1.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.0.1...v4.1.0) (2020-09-07) diff --git a/lerna.json b/lerna.json index ac3c715ea746..e4dacbc39913 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "4.1.0", + "version": "4.1.1", "npmClient": "yarn", "useWorkspaces": true, "stream": true diff --git a/packages/eslint-plugin-internal/CHANGELOG.md b/packages/eslint-plugin-internal/CHANGELOG.md index 824ea25060cc..d9e300285162 100644 --- a/packages/eslint-plugin-internal/CHANGELOG.md +++ b/packages/eslint-plugin-internal/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.1.1](https://github.com/typescript-eslint/typescript-eslint/compare/v4.1.0...v4.1.1) (2020-09-14) + +**Note:** Version bump only for package @typescript-eslint/eslint-plugin-internal + + + + + # [4.1.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.0.1...v4.1.0) (2020-09-07) **Note:** Version bump only for package @typescript-eslint/eslint-plugin-internal diff --git a/packages/eslint-plugin-internal/package.json b/packages/eslint-plugin-internal/package.json index 3393d3b4ddee..bacc4e4ee690 100644 --- a/packages/eslint-plugin-internal/package.json +++ b/packages/eslint-plugin-internal/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin-internal", - "version": "4.1.0", + "version": "4.1.1", "private": true, "main": "dist/index.js", "scripts": { @@ -14,7 +14,7 @@ }, "dependencies": { "@types/prettier": "*", - "@typescript-eslint/experimental-utils": "4.1.0", + "@typescript-eslint/experimental-utils": "4.1.1", "prettier": "*" } } diff --git a/packages/eslint-plugin-tslint/CHANGELOG.md b/packages/eslint-plugin-tslint/CHANGELOG.md index cce913d83422..bb8c58dd35e6 100644 --- a/packages/eslint-plugin-tslint/CHANGELOG.md +++ b/packages/eslint-plugin-tslint/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.1.1](https://github.com/typescript-eslint/typescript-eslint/compare/v4.1.0...v4.1.1) (2020-09-14) + +**Note:** Version bump only for package @typescript-eslint/eslint-plugin-tslint + + + + + # [4.1.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.0.1...v4.1.0) (2020-09-07) **Note:** Version bump only for package @typescript-eslint/eslint-plugin-tslint diff --git a/packages/eslint-plugin-tslint/package.json b/packages/eslint-plugin-tslint/package.json index 460838fadcb5..db79bccef266 100644 --- a/packages/eslint-plugin-tslint/package.json +++ b/packages/eslint-plugin-tslint/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin-tslint", - "version": "4.1.0", + "version": "4.1.1", "main": "dist/index.js", "typings": "src/index.ts", "description": "TSLint wrapper plugin for ESLint", @@ -38,7 +38,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/experimental-utils": "4.1.0", + "@typescript-eslint/experimental-utils": "4.1.1", "lodash": "^4.17.15" }, "peerDependencies": { @@ -48,6 +48,6 @@ }, "devDependencies": { "@types/lodash": "*", - "@typescript-eslint/parser": "4.1.0" + "@typescript-eslint/parser": "4.1.1" } } diff --git a/packages/eslint-plugin/CHANGELOG.md b/packages/eslint-plugin/CHANGELOG.md index 7bc2c3c4d1aa..c837f4965ea2 100644 --- a/packages/eslint-plugin/CHANGELOG.md +++ b/packages/eslint-plugin/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.1.1](https://github.com/typescript-eslint/typescript-eslint/compare/v4.1.0...v4.1.1) (2020-09-14) + + +### Bug Fixes + +* **eslint-plugin:** [naming-convention] allow an array of selectors with types and modifiers ([#2415](https://github.com/typescript-eslint/typescript-eslint/issues/2415)) ([7ca54c3](https://github.com/typescript-eslint/typescript-eslint/commit/7ca54c3e4601ad07db5b882a67965cd67a18c4b3)) +* **eslint-plugin:** [no-implied-eval] handle the `Function` type ([#2435](https://github.com/typescript-eslint/typescript-eslint/issues/2435)) ([e1401dc](https://github.com/typescript-eslint/typescript-eslint/commit/e1401dc5897d01da516802cfb2333cf4bc6d0e93)) +* **eslint-plugin:** [no-unused-vars] better handling for declared modules ([#2553](https://github.com/typescript-eslint/typescript-eslint/issues/2553)) ([02d72d4](https://github.com/typescript-eslint/typescript-eslint/commit/02d72d480be7a8f7ddc66a028338cfb996886f3c)), closes [#2523](https://github.com/typescript-eslint/typescript-eslint/issues/2523) +* **eslint-plugin:** [no-use-before-define] false positive for function type arguments ([#2554](https://github.com/typescript-eslint/typescript-eslint/issues/2554)) ([189162d](https://github.com/typescript-eslint/typescript-eslint/commit/189162d46ecb116c420232937a7f86df913f4e79)), closes [#2527](https://github.com/typescript-eslint/typescript-eslint/issues/2527) +* **eslint-plugin:** [prefer-function-type] handle `this` return ([#2437](https://github.com/typescript-eslint/typescript-eslint/issues/2437)) ([7c6fcee](https://github.com/typescript-eslint/typescript-eslint/commit/7c6fcee657dffd041e389e0aeaa4f3e278e92986)) +* **eslint-plugin:** [return-await] don't error for `in-try-catch` if the return is in a `catch` without a `finally` ([#2356](https://github.com/typescript-eslint/typescript-eslint/issues/2356)) ([efdd521](https://github.com/typescript-eslint/typescript-eslint/commit/efdd5213ceaef332cf0b2c26573176f844d22a09)) + + + + + # [4.1.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.0.1...v4.1.0) (2020-09-07) diff --git a/packages/eslint-plugin/ROADMAP.md b/packages/eslint-plugin/ROADMAP.md index c3f552058fa5..5d9724a194f8 100644 --- a/packages/eslint-plugin/ROADMAP.md +++ b/packages/eslint-plugin/ROADMAP.md @@ -388,7 +388,10 @@ Relevant plugins: [`chai-expect-keywords`](https://github.com/gavinaiken/eslint- [`no-invalid-this`]: https://palantir.github.io/tslint/rules/no-invalid-this [`no-misused-new`]: https://palantir.github.io/tslint/rules/no-misused-new [`no-null-keyword`]: https://palantir.github.io/tslint/rules/no-null-keyword +[`no-null-undefined-union`]: https://palantir.github.io/tslint/rules/no-null-undefined-union [`no-object-literal-type-assertion`]: https://palantir.github.io/tslint/rules/no-object-literal-type-assertion +[`no-promise-as-boolean`]: https://palantir.github.io/tslint/rules/no-promise-as-boolean +[`no-restricted-globals`]: https://palantir.github.io/tslint/rules/no-restricted-globals [`no-return-await`]: https://palantir.github.io/tslint/rules/no-return-await [`no-shadowed-variable`]: https://palantir.github.io/tslint/rules/no-shadowed-variable [`no-sparse-arrays`]: https://palantir.github.io/tslint/rules/no-sparse-arrays @@ -396,6 +399,7 @@ Relevant plugins: [`chai-expect-keywords`](https://github.com/gavinaiken/eslint- [`no-string-throw`]: https://palantir.github.io/tslint/rules/no-string-throw [`no-submodule-imports`]: https://palantir.github.io/tslint/rules/no-submodule-imports [`no-switch-case-fall-through`]: https://palantir.github.io/tslint/rules/no-switch-case-fall-through +[`no-tautology-expression`]: https://palantir.github.io/tslint/rules/no-tautology-expression [`no-this-assignment`]: https://palantir.github.io/tslint/rules/no-this-assignment [`no-unbound-method`]: https://palantir.github.io/tslint/rules/no-unbound-method [`no-unnecessary-class`]: https://palantir.github.io/tslint/rules/no-unnecessary-class @@ -410,7 +414,9 @@ Relevant plugins: [`chai-expect-keywords`](https://github.com/gavinaiken/eslint- [`prefer-object-spread`]: https://palantir.github.io/tslint/rules/prefer-object-spread [`radix`]: https://palantir.github.io/tslint/rules/radix [`restrict-plus-operands`]: https://palantir.github.io/tslint/rules/restrict-plus-operands +[`static-this`]: https://palantir.github.io/tslint/rules/static-this [`strict-boolean-expressions`]: https://palantir.github.io/tslint/rules/strict-boolean-expressions +[`strict-string-expressions`]: https://palantir.github.io/tslint/rules/strict-string-expressions [`strict-type-predicates`]: https://palantir.github.io/tslint/rules/strict-type-predicates [`switch-default`]: https://palantir.github.io/tslint/rules/switch-default [`triple-equals`]: https://palantir.github.io/tslint/rules/triple-equals @@ -466,6 +472,7 @@ Relevant plugins: [`chai-expect-keywords`](https://github.com/gavinaiken/eslint- [`no-reference-import`]: https://palantir.github.io/tslint/rules/no-reference-import [`no-trailing-whitespace`]: https://palantir.github.io/tslint/rules/no-trailing-whitespace [`no-unnecessary-callback-wrapper`]: https://palantir.github.io/tslint/rules/no-unnecessary-callback-wrapper +[`no-unnecessary-else`]: https://palantir.github.io/tslint/rules/no-unnecessary-else [`no-unnecessary-initializer`]: https://palantir.github.io/tslint/rules/no-unnecessary-initializer [`no-unnecessary-qualifier`]: https://palantir.github.io/tslint/rules/no-unnecessary-qualifier [`number-literal-format`]: https://palantir.github.io/tslint/rules/number-literal-format diff --git a/packages/eslint-plugin/docs/rules/prefer-function-type.md b/packages/eslint-plugin/docs/rules/prefer-function-type.md index a3210a133a6e..5c3bc55c9f2c 100644 --- a/packages/eslint-plugin/docs/rules/prefer-function-type.md +++ b/packages/eslint-plugin/docs/rules/prefer-function-type.md @@ -24,6 +24,13 @@ interface Foo extends Function { } ``` +```ts +interface MixinMethod { + // returns the function itself, not the `this` argument. + (arg: string): this; +} +``` + Examples of **correct** code for this rule: ```ts @@ -48,6 +55,23 @@ interface Bar extends Foo { } ``` +```ts +// returns the `this` argument of function, retaining it's type. +type MixinMethod = (this: TSelf, arg: string) => TSelf; +// a function that returns itself is much clearer in this form. +type ReturnsSelf = (arg: string) => ReturnsSelf; +``` + +```ts +// multiple call signatures (overloads) is allowed: +interface Overloaded { + (data: string): number; + (id: number): string; +} +// this is equivelent to Overloaded interface. +type Intersection = ((data: string) => number) & ((id: number) => string); +``` + ## When Not To Use It If you specifically want to use an interface or type literal with a single call signature for stylistic reasons, you can disable this rule. diff --git a/packages/eslint-plugin/docs/rules/return-await.md b/packages/eslint-plugin/docs/rules/return-await.md index 1f0adc71ec1f..3c621d251044 100644 --- a/packages/eslint-plugin/docs/rules/return-await.md +++ b/packages/eslint-plugin/docs/rules/return-await.md @@ -28,6 +28,12 @@ const defaultOptions: Options = 'in-try-catch'; ### `in-try-catch` Requires that a returned promise must be `await`ed in `try-catch-finally` blocks, and disallows it elsewhere. +Specifically: + +- if you `return` a promise within a `try`, then it must be `await`ed. +- if you `return` a promise within a `catch`, and there **_is no_** `finally`, then it **_must not_** be `await`ed. +- if you `return` a promise within a `catch`, and there **_is a_** `finally`, then it **_must_** be `await`ed. +- if you `return` a promise within a `finally`, then it **_must not_** be `await`ed. Examples of **incorrect** code with `in-try-catch`: @@ -39,10 +45,38 @@ async function invalidInTryCatch1() { } async function invalidInTryCatch2() { - return await Promise.resolve('try'); + try { + throw new Error('error'); + } catch (e) { + return await Promise.resolve('catch'); + } } async function invalidInTryCatch3() { + try { + throw new Error('error'); + } catch (e) { + return Promise.resolve('catch'); + } finally { + console.log('cleanup'); + } +} + +async function invalidInTryCatch4() { + try { + throw new Error('error'); + } catch (e) { + throw new Error('error2'); + } finally { + return await Promise.resolve('finally'); + } +} + +async function invalidInTryCatch5() { + return await Promise.resolve('try'); +} + +async function invalidInTryCatch6() { return await 'value'; } ``` @@ -57,10 +91,38 @@ async function validInTryCatch1() { } async function validInTryCatch2() { - return Promise.resolve('try'); + try { + throw new Error('error'); + } catch (e) { + return Promise.resolve('catch'); + } } async function validInTryCatch3() { + try { + throw new Error('error'); + } catch (e) { + return await Promise.resolve('catch'); + } finally { + console.log('cleanup'); + } +} + +async function validInTryCatch4() { + try { + throw new Error('error'); + } catch (e) { + throw new Error('error2'); + } finally { + return Promise.resolve('finally'); + } +} + +async function validInTryCatch5() { + return Promise.resolve('try'); +} + +async function validInTryCatch6() { return 'value'; } ``` diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 581610236872..170351bff680 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin", - "version": "4.1.0", + "version": "4.1.1", "description": "TypeScript plugin for ESLint", "keywords": [ "eslint", @@ -42,8 +42,8 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/experimental-utils": "4.1.0", - "@typescript-eslint/scope-manager": "4.1.0", + "@typescript-eslint/experimental-utils": "4.1.1", + "@typescript-eslint/scope-manager": "4.1.1", "debug": "^4.1.1", "functional-red-black-tree": "^1.0.1", "regexpp": "^3.0.0", diff --git a/packages/eslint-plugin/src/rules/naming-convention.ts b/packages/eslint-plugin/src/rules/naming-convention.ts index 7d40e0862cb0..fb814e17e047 100644 --- a/packages/eslint-plugin/src/rules/naming-convention.ts +++ b/packages/eslint-plugin/src/rules/naming-convention.ts @@ -278,28 +278,29 @@ function selectorsSchema(): JSONSchema.JSONSchema4 { }, additionalItems: false, }, + modifiers: { + type: 'array', + items: { + type: 'string', + enum: util.getEnumNames(Modifiers), + }, + additionalItems: false, + }, + types: { + type: 'array', + items: { + type: 'string', + enum: util.getEnumNames(TypeModifiers), + }, + additionalItems: false, + }, }, }, - modifiers: { - type: 'array', - items: { - type: 'string', - enum: util.getEnumNames(Modifiers), - }, - additionalItems: false, - }, - types: { - type: 'array', - items: { - type: 'string', - enum: util.getEnumNames(TypeModifiers), - }, - additionalItems: false, - }, required: ['selector', 'format'], additionalProperties: false, }; } + const SCHEMA: JSONSchema.JSONSchema4 = { type: 'array', items: { @@ -819,7 +820,9 @@ type ParsedOptions = Record; type Context = Readonly>; function parseOptions(context: Context): ParsedOptions { - const normalizedOptions = context.options.map(opt => normalizeOption(opt)); + const normalizedOptions = context.options + .map(opt => normalizeOption(opt)) + .reduce((acc, val) => acc.concat(val), []); return util.getEnumNames(Selectors).reduce((acc, k) => { acc[k] = createValidator(k, context, normalizedOptions); return acc; @@ -1257,7 +1260,8 @@ function isMetaSelector( ): selector is MetaSelectorsString { return selector in MetaSelectors; } -function normalizeOption(option: Selector): NormalizedSelector { + +function normalizeOption(option: Selector): NormalizedSelector[] { let weight = 0; option.modifiers?.forEach(mod => { weight |= Modifiers[mod]; @@ -1309,16 +1313,30 @@ function normalizeOption(option: Selector): NormalizedSelector { ? option.selector : [option.selector]; - return { - selector: selectors - .map(selector => - isMetaSelector(selector) - ? MetaSelectors[selector] - : Selectors[selector], - ) - .reduce((accumulator, selector) => accumulator | selector), - ...normalizedOption, - }; + const selectorsAllowedToHaveTypes: (Selectors | MetaSelectors)[] = [ + Selectors.variable, + Selectors.parameter, + Selectors.property, + Selectors.parameterProperty, + Selectors.accessor, + ]; + + const config: NormalizedSelector[] = []; + selectors + .map(selector => + isMetaSelector(selector) ? MetaSelectors[selector] : Selectors[selector], + ) + .forEach(selector => + selectorsAllowedToHaveTypes.includes(selector) + ? config.push({ selector: selector, ...normalizedOption }) + : config.push({ + selector: selector, + ...normalizedOption, + types: null, + }), + ); + + return config; } function isCorrectType( diff --git a/packages/eslint-plugin/src/rules/no-implied-eval.ts b/packages/eslint-plugin/src/rules/no-implied-eval.ts index afda630b6b6c..1e063847da3f 100644 --- a/packages/eslint-plugin/src/rules/no-implied-eval.ts +++ b/packages/eslint-plugin/src/rules/no-implied-eval.ts @@ -80,6 +80,16 @@ export default util.createRule({ return true; } + if (symbol && symbol.escapedName === FUNCTION_CONSTRUCTOR) { + const declarations = symbol.getDeclarations() ?? []; + for (const declaration of declarations) { + const sourceFile = declaration.getSourceFile(); + if (program.isSourceFileDefaultLibrary(sourceFile)) { + return true; + } + } + } + const signatures = checker.getSignaturesOfType( type, ts.SignatureKind.Call, diff --git a/packages/eslint-plugin/src/rules/no-unused-vars.ts b/packages/eslint-plugin/src/rules/no-unused-vars.ts index 03c27d406167..7239982c9356 100644 --- a/packages/eslint-plugin/src/rules/no-unused-vars.ts +++ b/packages/eslint-plugin/src/rules/no-unused-vars.ts @@ -219,6 +219,19 @@ export default util.createRule({ markDeclarationChildAsUsed(node); }, + // global augmentation can be in any file, and they do not need exports + 'TSModuleDeclaration[declare = true][global = true]'(): void { + context.markVariableAsUsed('global'); + }, + + // children of a namespace that is a child of a declared namespace are auto-exported + [ambientDeclarationSelector( + 'TSModuleDeclaration[declare = true] > TSModuleBlock TSModuleDeclaration > TSModuleBlock', + false, + )](node: DeclarationSelectorNode): void { + markDeclarationChildAsUsed(node); + }, + // declared namespace handling [ambientDeclarationSelector( 'TSModuleDeclaration[declare = true] > TSModuleBlock', @@ -229,9 +242,12 @@ export default util.createRule({ util.NullThrowsReasons.MissingParent, ) as TSESTree.TSModuleDeclaration; - // declared modules with an `export =` statement will only export that one thing + // declared ambient modules with an `export =` statement will only export that one thing // all other statements are not automatically exported in this case - if (checkModuleDeclForExportEquals(moduleDecl)) { + if ( + moduleDecl.id.type === AST_NODE_TYPES.Literal && + checkModuleDeclForExportEquals(moduleDecl) + ) { return; } @@ -284,7 +300,7 @@ export default util.createRule({ AST_NODE_TYPES.TSEnumDeclaration, AST_NODE_TYPES.TSModuleDeclaration, AST_NODE_TYPES.VariableDeclaration, - ].join(', ')})${childDeclare ? '[declare=true]' : ''}`, + ].join(', ')})${childDeclare ? '[declare = true]' : ''}`, ].join(', '); } function markDeclarationChildAsUsed(node: DeclarationSelectorNode): void { 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 1e26e4729f93..18525a138ced 100644 --- a/packages/eslint-plugin/src/rules/no-use-before-define.ts +++ b/packages/eslint-plugin/src/rules/no-use-before-define.ts @@ -260,7 +260,8 @@ export default util.createRule({ variable.identifiers.length === 0 || (variable.identifiers[0].range[1] <= reference.identifier.range[1] && !isInInitializer(variable, reference)) || - !isForbidden(variable, reference) + !isForbidden(variable, reference) || + reference.from.type === TSESLint.Scope.ScopeType.functionType ) { return; } diff --git a/packages/eslint-plugin/src/rules/prefer-function-type.ts b/packages/eslint-plugin/src/rules/prefer-function-type.ts index dae4fae32956..1d8c27012101 100644 --- a/packages/eslint-plugin/src/rules/prefer-function-type.ts +++ b/packages/eslint-plugin/src/rules/prefer-function-type.ts @@ -5,6 +5,11 @@ import { } from '@typescript-eslint/experimental-utils'; import * as util from '../util'; +export const phrases = { + [AST_NODE_TYPES.TSTypeLiteral]: 'Type literal', + [AST_NODE_TYPES.TSInterfaceDeclaration]: 'Interface', +} as const; + export default util.createRule({ name: 'prefer-function-type', meta: { @@ -17,7 +22,9 @@ export default util.createRule({ fixable: 'code', messages: { functionTypeOverCallableType: - "{{ type }} has only a call signature - use '{{ sigSuggestion }}' instead.", + '{{ literalOrInterface }} only has a call signature, you should use a function type instead.', + unexpectedThisOnFunctionOnlyInterface: + "`this` refers to the function type '{{ interfaceName }}', did you intend to use a generic `this` parameter like `(this: Self, ...) => Self` instead?", }, schema: [], type: 'suggestion', @@ -104,13 +111,30 @@ export default util.createRule({ */ function checkMember( member: TSESTree.TypeElement, - node: TSESTree.Node, + node: TSESTree.TSInterfaceDeclaration | TSESTree.TSTypeLiteral, + tsThisTypes: TSESTree.TSThisType[] | null = null, ): void { if ( (member.type === AST_NODE_TYPES.TSCallSignatureDeclaration || member.type === AST_NODE_TYPES.TSConstructSignatureDeclaration) && typeof member.returnType !== 'undefined' ) { + if ( + tsThisTypes !== null && + tsThisTypes.length > 0 && + node.type === AST_NODE_TYPES.TSInterfaceDeclaration + ) { + // the message can be confusing if we don't point directly to the `this` node instead of the whole member + // and in favour of generating at most one error we'll only report the first occurrence of `this` if there are multiple + context.report({ + node: tsThisTypes[0], + messageId: 'unexpectedThisOnFunctionOnlyInterface', + data: { + interfaceName: node.id.name, + }, + }); + return; + } const suggestion = renderSuggestion(member, node); const fixStart = node.type === AST_NODE_TYPES.TSTypeLiteral @@ -127,11 +151,7 @@ export default util.createRule({ node: member, messageId: 'functionTypeOverCallableType', data: { - type: - node.type === AST_NODE_TYPES.TSTypeLiteral - ? 'Type literal' - : 'Interface', - sigSuggestion: suggestion, + literalOrInterface: phrases[node.type], }, fix(fixer) { return fixer.replaceTextRange( @@ -142,12 +162,36 @@ export default util.createRule({ }); } } - + let tsThisTypes: TSESTree.TSThisType[] | null = null; + let literalNesting = 0; return { - TSInterfaceDeclaration(node): void { + TSInterfaceDeclaration(): void { + // when entering an interface reset the count of `this`s to empty. + tsThisTypes = []; + }, + 'TSInterfaceDeclaration TSThisType'(node: TSESTree.TSThisType): void { + // inside an interface keep track of all ThisType references. + // unless it's inside a nested type literal in which case it's invalid code anyway + // we don't want to incorrectly say "it refers to name" while typescript says it's completely invalid. + if (literalNesting === 0 && tsThisTypes !== null) { + tsThisTypes.push(node); + } + }, + 'TSInterfaceDeclaration:exit'( + node: TSESTree.TSInterfaceDeclaration, + ): void { if (!hasOneSupertype(node) && node.body.body.length === 1) { - checkMember(node.body.body[0], node); + checkMember(node.body.body[0], node, tsThisTypes); } + // on exit check member and reset the array to nothing. + tsThisTypes = null; + }, + // keep track of nested literals to avoid complaining about invalid `this` uses + 'TSInterfaceDeclaration TSTypeLiteral'(): void { + literalNesting += 1; + }, + 'TSInterfaceDeclaration TSTypeLiteral:exit'(): void { + literalNesting -= 1; }, 'TSTypeLiteral[members.length = 1]'(node: TSESTree.TSTypeLiteral): void { checkMember(node.members[0], node); diff --git a/packages/eslint-plugin/src/rules/return-await.ts b/packages/eslint-plugin/src/rules/return-await.ts index 17bc9c0e54ec..edbfcb593ed4 100644 --- a/packages/eslint-plugin/src/rules/return-await.ts +++ b/packages/eslint-plugin/src/rules/return-await.ts @@ -57,23 +57,63 @@ export default util.createRule({ }; } - function inTryCatch(node: ts.Node): boolean { + function inTry(node: ts.Node): boolean { + let ancestor = node.parent; + + while (ancestor && !ts.isFunctionLike(ancestor)) { + if (tsutils.isTryStatement(ancestor)) { + return true; + } + + ancestor = ancestor.parent; + } + + return false; + } + + function inCatch(node: ts.Node): boolean { + let ancestor = node.parent; + + while (ancestor && !ts.isFunctionLike(ancestor)) { + if (tsutils.isCatchClause(ancestor)) { + return true; + } + + ancestor = ancestor.parent; + } + + return false; + } + + function isReturnPromiseInFinally(node: ts.Node): boolean { let ancestor = node.parent; while (ancestor && !ts.isFunctionLike(ancestor)) { if ( - tsutils.isTryStatement(ancestor) || - tsutils.isCatchClause(ancestor) + tsutils.isTryStatement(ancestor.parent) && + tsutils.isBlock(ancestor) && + ancestor.parent.end === ancestor.end ) { return true; } - ancestor = ancestor.parent; } return false; } + function hasFinallyBlock(node: ts.Node): boolean { + let ancestor = node.parent; + + while (ancestor && !ts.isFunctionLike(ancestor)) { + if (tsutils.isTryStatement(ancestor)) { + return !!ancestor.finallyBlock; + } + ancestor = ancestor.parent; + } + return false; + } + // function findTokensToRemove() function removeAwait( @@ -163,7 +203,7 @@ export default util.createRule({ } if (option === 'in-try-catch') { - const isInTryCatch = inTryCatch(expression); + const isInTryCatch = inTry(expression) || inCatch(expression); if (isAwait && !isInTryCatch) { context.report({ messageId: 'disallowedPromiseAwait', @@ -171,6 +211,14 @@ export default util.createRule({ fix: fixer => removeAwait(fixer, node), }); } else if (!isAwait && isInTryCatch) { + if (inCatch(expression) && !hasFinallyBlock(expression)) { + return; + } + + if (isReturnPromiseInFinally(expression)) { + return; + } + context.report({ messageId: 'requiredPromiseAwait', node, diff --git a/packages/eslint-plugin/tests/rules/naming-convention.test.ts b/packages/eslint-plugin/tests/rules/naming-convention.test.ts index 040c2f7eba4f..8c855b3a8a51 100644 --- a/packages/eslint-plugin/tests/rules/naming-convention.test.ts +++ b/packages/eslint-plugin/tests/rules/naming-convention.test.ts @@ -835,6 +835,77 @@ ruleTester.run('naming-convention', rule, { }, ], }, + { + code: ` + let isFoo = 1; + class foo { + shouldBoo: number; + } + `, + parserOptions, + options: [ + { + selector: ['variable', 'parameter', 'property', 'accessor'], + types: ['number'], + format: ['PascalCase'], + prefix: ['is', 'should', 'has', 'can', 'did', 'will'], + }, + ], + }, + { + code: ` + class foo { + private readonly FooBoo: boolean; + } + `, + parserOptions, + options: [ + { + selector: ['property', 'accessor'], + types: ['boolean'], + modifiers: ['private', 'readonly'], + format: ['PascalCase'], + }, + ], + }, + { + code: ` + class foo { + private fooBoo: number; + } + `, + options: [ + { + selector: ['property', 'accessor'], + modifiers: ['private'], + format: ['camelCase'], + }, + ], + }, + { + code: ` + const isfooBar = 1; + function fun(goodfunFoo: number) {} + class foo { + private VanFooBar: number; + } + `, + parserOptions, + options: [ + { + selector: ['property', 'accessor'], + modifiers: ['private'], + format: ['StrictPascalCase'], + prefix: ['Van'], + }, + { + selector: ['variable', 'parameter'], + types: ['number'], + format: ['camelCase'], + prefix: ['is', 'good'], + }, + ], + }, ], invalid: [ { @@ -871,19 +942,16 @@ ruleTester.run('naming-convention', rule, { declare const any_camelCase01: any; declare const any_camelCase02: any | null; declare const any_camelCase03: any | null | undefined; - declare const string_camelCase01: string; declare const string_camelCase02: string | null; declare const string_camelCase03: string | null | undefined; declare const string_camelCase04: 'a' | null | undefined; declare const string_camelCase05: string | 'a' | null | undefined; - declare const number_camelCase06: number; declare const number_camelCase07: number | null; declare const number_camelCase08: number | null | undefined; declare const number_camelCase09: 1 | null | undefined; declare const number_camelCase10: number | 2 | null | undefined; - declare const boolean_camelCase11: boolean; declare const boolean_camelCase12: boolean | null; declare const boolean_camelCase13: boolean | null | undefined; @@ -955,7 +1023,6 @@ ruleTester.run('naming-convention', rule, { | undefined; declare const array_camelCase6: [] | null | undefined; declare const array_camelCase7: [number] | null | undefined; - declare const array_camelCase8: | readonly number[] | Array @@ -1166,5 +1233,54 @@ ruleTester.run('naming-convention', rule, { }, ], }, + { + code: ` + const myfoo_bar = 'abcs'; + function fun(myfoo: string) {} + class foo { + Myfoo: string; + } + `, + options: [ + { + selector: ['variable', 'property', 'parameter'], + types: ['string'], + format: ['PascalCase'], + prefix: ['my', 'My'], + }, + ], + parserOptions, + errors: Array(3).fill({ messageId: 'doesNotMatchFormatTrimmed' }), + }, + { + code: ` + class foo { + private readonly fooBar: boolean; + } + `, + options: [ + { + selector: ['property', 'accessor'], + modifiers: ['private', 'readonly'], + format: ['PascalCase'], + }, + ], + errors: [{ messageId: 'doesNotMatchFormat' }], + }, + { + code: ` + function my_foo_bar() {} + `, + parserOptions, + options: [ + { + selector: ['variable', 'function'], + types: ['string'], + format: ['PascalCase'], + prefix: ['my', 'My'], + }, + ], + errors: [{ messageId: 'doesNotMatchFormatTrimmed' }], + }, ], }); diff --git a/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts b/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts index f5ceba4fe94a..a9867d73018d 100644 --- a/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts +++ b/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts @@ -246,6 +246,11 @@ const fn = (foo: () => void) => { import { Function } from './class'; new Function('foo'); `, + ` +const foo = (callback: Function) => { + setTimeout(callback, 0); +}; + `, ], invalid: [ 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 fbb468e375f5..e22f9eb2ba7c 100644 --- a/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts @@ -858,6 +858,32 @@ declare module 'foo' { type Test = 1; const x: Test = 1; export = x; +} + `, + // https://github.com/typescript-eslint/typescript-eslint/issues/2523 + ` +declare global { + interface Foo {} +} + `, + ` +declare global { + namespace jest { + interface Matchers { + toBeSeven: () => R; + } + } +} + `, + ` +export declare namespace Foo { + namespace Bar { + namespace Baz { + namespace Bam { + const x = 1; + } + } + } } `, ], @@ -1456,5 +1482,57 @@ declare module 'foo' { }, ], }, + { + code: ` +// not declared +export namespace Foo { + namespace Bar { + namespace Baz { + namespace Bam { + const x = 1; + } + } + } +} + `, + errors: [ + { + messageId: 'unusedVar', + line: 4, + data: { + varName: 'Bar', + action: 'defined', + additional: '', + }, + }, + { + messageId: 'unusedVar', + line: 5, + data: { + varName: 'Baz', + action: 'defined', + additional: '', + }, + }, + { + messageId: 'unusedVar', + line: 6, + data: { + varName: 'Bam', + action: 'defined', + additional: '', + }, + }, + { + messageId: 'unusedVar', + line: 7, + data: { + varName: 'x', + action: 'assigned a value', + additional: '', + }, + }, + ], + }, ], }); 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 85dec218d112..ad66ff7858e5 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 @@ -343,6 +343,10 @@ const React = require('react'); }, }, }, + // https://github.com/typescript-eslint/typescript-eslint/issues/2527 + ` +type T = (value: unknown) => value is Id; + `, ], invalid: [ { 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 257bd9e20d85..d294041fbaf1 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/experimental-utils'; -import rule from '../../src/rules/prefer-function-type'; -import { RuleTester } from '../RuleTester'; +import rule, { phrases } from '../../src/rules/prefer-function-type'; +import { noFormat, RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { @@ -56,6 +56,9 @@ interface Foo { { messageId: 'functionTypeOverCallableType', type: AST_NODE_TYPES.TSCallSignatureDeclaration, + data: { + literalOrInterface: phrases[AST_NODE_TYPES.TSInterfaceDeclaration], + }, }, ], output: ` @@ -72,6 +75,9 @@ type Foo = { { messageId: 'functionTypeOverCallableType', type: AST_NODE_TYPES.TSCallSignatureDeclaration, + data: { + literalOrInterface: phrases[AST_NODE_TYPES.TSTypeLiteral], + }, }, ], output: ` @@ -88,6 +94,9 @@ function foo(bar: { (s: string): number }): number { { messageId: 'functionTypeOverCallableType', type: AST_NODE_TYPES.TSCallSignatureDeclaration, + data: { + literalOrInterface: phrases[AST_NODE_TYPES.TSTypeLiteral], + }, }, ], output: ` @@ -106,6 +115,9 @@ function foo(bar: { (s: string): number } | undefined): number { { messageId: 'functionTypeOverCallableType', type: AST_NODE_TYPES.TSCallSignatureDeclaration, + data: { + literalOrInterface: phrases[AST_NODE_TYPES.TSTypeLiteral], + }, }, ], output: ` @@ -124,6 +136,9 @@ interface Foo extends Function { { messageId: 'functionTypeOverCallableType', type: AST_NODE_TYPES.TSCallSignatureDeclaration, + data: { + literalOrInterface: phrases[AST_NODE_TYPES.TSInterfaceDeclaration], + }, }, ], output: ` @@ -140,11 +155,118 @@ interface Foo { { messageId: 'functionTypeOverCallableType', type: AST_NODE_TYPES.TSCallSignatureDeclaration, + data: { + literalOrInterface: phrases[AST_NODE_TYPES.TSInterfaceDeclaration], + }, }, ], output: ` type Foo = (bar: T) => string; `, }, + { + code: ` +interface Foo { + (this: T): void; +} + `, + errors: [ + { + messageId: 'functionTypeOverCallableType', + type: AST_NODE_TYPES.TSCallSignatureDeclaration, + data: { + literalOrInterface: phrases[AST_NODE_TYPES.TSInterfaceDeclaration], + }, + }, + ], + output: ` +type Foo = (this: T) => void; + `, + }, + { + code: ` +type Foo = { (this: string): T }; + `, + errors: [ + { + messageId: 'functionTypeOverCallableType', + type: AST_NODE_TYPES.TSCallSignatureDeclaration, + data: { + literalOrInterface: phrases[AST_NODE_TYPES.TSTypeLiteral], + }, + }, + ], + output: ` +type Foo = (this: string) => T; + `, + }, + { + code: ` +interface Foo { + (arg: this): void; +} + `, + errors: [ + { + messageId: 'unexpectedThisOnFunctionOnlyInterface', + type: AST_NODE_TYPES.TSThisType, + data: { + interfaceName: 'Foo', + }, + }, + ], + }, + { + code: ` +interface Foo { + (arg: number): this | undefined; +} + `, + errors: [ + { + messageId: 'unexpectedThisOnFunctionOnlyInterface', + type: AST_NODE_TYPES.TSThisType, + data: { + interfaceName: 'Foo', + }, + }, + ], + }, + { + code: ` +interface Foo { + // isn't actually valid ts but want to not give message saying it refers to Foo. + (): { + a: { + nested: this; + }; + between: this; + b: { + nested: string; + }; + }; +} + `, + errors: [ + { + messageId: 'functionTypeOverCallableType', + type: AST_NODE_TYPES.TSCallSignatureDeclaration, + data: { + literalOrInterface: phrases[AST_NODE_TYPES.TSInterfaceDeclaration], + }, + }, + ], + output: noFormat` +type Foo = () => { + a: { + nested: this; + }; + between: this; + b: { + nested: string; + }; + }; + `, + }, ], }); diff --git a/packages/eslint-plugin/tests/rules/return-await.test.ts b/packages/eslint-plugin/tests/rules/return-await.test.ts index 671374fc9bd1..887768a6106b 100644 --- a/packages/eslint-plugin/tests/rules/return-await.test.ts +++ b/packages/eslint-plugin/tests/rules/return-await.test.ts @@ -112,6 +112,32 @@ ruleTester.run('return-await', rule, { } `, }, + { + options: ['in-try-catch'], + code: ` + async function test() { + try { + throw 'foo'; + } catch (e) { + return Promise.resolve(1); + } + } + `, + }, + { + options: ['in-try-catch'], + code: ` + async function test() { + try { + throw 'foo'; + } catch (e) { + throw 'foo2'; + } finally { + return Promise.resolve(1); + } + } + `, + }, { options: ['in-try-catch'], code: ` diff --git a/packages/experimental-utils/CHANGELOG.md b/packages/experimental-utils/CHANGELOG.md index b32112bea0ec..7a004064b69f 100644 --- a/packages/experimental-utils/CHANGELOG.md +++ b/packages/experimental-utils/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.1.1](https://github.com/typescript-eslint/typescript-eslint/compare/v4.1.0...v4.1.1) (2020-09-14) + + +### Bug Fixes + +* **eslint-plugin:** [no-use-before-define] false positive for function type arguments ([#2554](https://github.com/typescript-eslint/typescript-eslint/issues/2554)) ([189162d](https://github.com/typescript-eslint/typescript-eslint/commit/189162d46ecb116c420232937a7f86df913f4e79)), closes [#2527](https://github.com/typescript-eslint/typescript-eslint/issues/2527) + + + + + # [4.1.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.0.1...v4.1.0) (2020-09-07) **Note:** Version bump only for package @typescript-eslint/experimental-utils diff --git a/packages/experimental-utils/package.json b/packages/experimental-utils/package.json index 4663aed76229..26380f215895 100644 --- a/packages/experimental-utils/package.json +++ b/packages/experimental-utils/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/experimental-utils", - "version": "4.1.0", + "version": "4.1.1", "description": "(Experimental) Utilities for working with TypeScript + ESLint together", "keywords": [ "eslint", @@ -40,9 +40,9 @@ }, "dependencies": { "@types/json-schema": "^7.0.3", - "@typescript-eslint/scope-manager": "4.1.0", - "@typescript-eslint/types": "4.1.0", - "@typescript-eslint/typescript-estree": "4.1.0", + "@typescript-eslint/scope-manager": "4.1.1", + "@typescript-eslint/types": "4.1.1", + "@typescript-eslint/typescript-estree": "4.1.1", "eslint-scope": "^5.0.0", "eslint-utils": "^2.0.0" }, diff --git a/packages/experimental-utils/src/ts-eslint/Scope.ts b/packages/experimental-utils/src/ts-eslint/Scope.ts index 2a7f707a429b..2934a4d27561 100644 --- a/packages/experimental-utils/src/ts-eslint/Scope.ts +++ b/packages/experimental-utils/src/ts-eslint/Scope.ts @@ -46,9 +46,11 @@ namespace Scope { export type Reference = scopeManager.Reference; export type Variable = scopeManager.Variable | ESLintScopeVariable; export type Scope = scopeManager.Scope; + export const ScopeType = scopeManager.ScopeType; // TODO - in the next major, clean this up with a breaking change export type DefinitionType = scopeManager.Definition; export type Definition = scopeManager.Definition; + export const DefinitionType = scopeManager.DefinitionType; } export { Scope }; diff --git a/packages/parser/CHANGELOG.md b/packages/parser/CHANGELOG.md index 8007f5601dbf..5eaec7bf0073 100644 --- a/packages/parser/CHANGELOG.md +++ b/packages/parser/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.1.1](https://github.com/typescript-eslint/typescript-eslint/compare/v4.1.0...v4.1.1) (2020-09-14) + +**Note:** Version bump only for package @typescript-eslint/parser + + + + + # [4.1.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.0.1...v4.1.0) (2020-09-07) diff --git a/packages/parser/package.json b/packages/parser/package.json index 43c6d09f30f1..14af7bb7876a 100644 --- a/packages/parser/package.json +++ b/packages/parser/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/parser", - "version": "4.1.0", + "version": "4.1.1", "description": "An ESLint custom parser which leverages TypeScript ESTree", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -44,15 +44,15 @@ "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" }, "dependencies": { - "@typescript-eslint/scope-manager": "4.1.0", - "@typescript-eslint/types": "4.1.0", - "@typescript-eslint/typescript-estree": "4.1.0", + "@typescript-eslint/scope-manager": "4.1.1", + "@typescript-eslint/types": "4.1.1", + "@typescript-eslint/typescript-estree": "4.1.1", "debug": "^4.1.1" }, "devDependencies": { "@types/glob": "*", - "@typescript-eslint/experimental-utils": "4.1.0", - "@typescript-eslint/shared-fixtures": "4.1.0", + "@typescript-eslint/experimental-utils": "4.1.1", + "@typescript-eslint/shared-fixtures": "4.1.1", "glob": "*", "typescript": "*" }, diff --git a/packages/scope-manager/CHANGELOG.md b/packages/scope-manager/CHANGELOG.md index cf0ad482f407..9d51f4928c7a 100644 --- a/packages/scope-manager/CHANGELOG.md +++ b/packages/scope-manager/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.1.1](https://github.com/typescript-eslint/typescript-eslint/compare/v4.1.0...v4.1.1) (2020-09-14) + +**Note:** Version bump only for package @typescript-eslint/scope-manager + + + + + # [4.1.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.0.1...v4.1.0) (2020-09-07) diff --git a/packages/scope-manager/package.json b/packages/scope-manager/package.json index e742ca647030..4888d82f0d95 100644 --- a/packages/scope-manager/package.json +++ b/packages/scope-manager/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/scope-manager", - "version": "4.1.0", + "version": "4.1.1", "description": "TypeScript scope analyser for ESLint", "keywords": [ "eslint", @@ -39,12 +39,12 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/types": "4.1.0", - "@typescript-eslint/visitor-keys": "4.1.0" + "@typescript-eslint/types": "4.1.1", + "@typescript-eslint/visitor-keys": "4.1.1" }, "devDependencies": { "@types/glob": "*", - "@typescript-eslint/typescript-estree": "4.1.0", + "@typescript-eslint/typescript-estree": "4.1.1", "glob": "*", "jest-specific-snapshot": "*", "make-dir": "*", diff --git a/packages/shared-fixtures/CHANGELOG.md b/packages/shared-fixtures/CHANGELOG.md index cb24845533c0..1c35480acf0d 100644 --- a/packages/shared-fixtures/CHANGELOG.md +++ b/packages/shared-fixtures/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.1.1](https://github.com/typescript-eslint/typescript-eslint/compare/v4.1.0...v4.1.1) (2020-09-14) + +**Note:** Version bump only for package @typescript-eslint/shared-fixtures + + + + + # [4.1.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.0.1...v4.1.0) (2020-09-07) **Note:** Version bump only for package @typescript-eslint/shared-fixtures diff --git a/packages/shared-fixtures/package.json b/packages/shared-fixtures/package.json index 7b4fb65a6f27..878a59b7be0c 100644 --- a/packages/shared-fixtures/package.json +++ b/packages/shared-fixtures/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/shared-fixtures", - "version": "4.1.0", + "version": "4.1.1", "private": true, "scripts": { "build": "tsc -b tsconfig.build.json", diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md index 43d03464c10d..2ff5f13b0997 100644 --- a/packages/types/CHANGELOG.md +++ b/packages/types/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.1.1](https://github.com/typescript-eslint/typescript-eslint/compare/v4.1.0...v4.1.1) (2020-09-14) + + +### Bug Fixes + +* **types:** artificial fix needed to trigger release ([b577daf](https://github.com/typescript-eslint/typescript-eslint/commit/b577daf27cd87870b6e095e4e995519f96d321dd)) + + + + + # [4.1.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.0.1...v4.1.0) (2020-09-07) diff --git a/packages/types/package.json b/packages/types/package.json index 5ea0f558132b..93802edaf379 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/types", - "version": "4.1.0", + "version": "4.1.1", "description": "Types for the TypeScript-ESTree AST spec", "keywords": [ "eslint", diff --git a/packages/types/src/ast-node-types.ts b/packages/types/src/ast-node-types.ts index d6523eb5c4ab..36699864ede0 100644 --- a/packages/types/src/ast-node-types.ts +++ b/packages/types/src/ast-node-types.ts @@ -169,10 +169,13 @@ export { AST_NODE_TYPES }; import type { Node } from './ts-estree'; type GetKeys = keyof Extract; + type AllKeys = { readonly [T in AST_NODE_TYPES]: GetKeys; }; + type TakesString> = T; + // @ts-expect-error: purposely unused type _Test = // forcing the test onto a new line so it isn't covered by the expect error diff --git a/packages/typescript-estree/CHANGELOG.md b/packages/typescript-estree/CHANGELOG.md index 284d90a3f8cf..0c273b67bfd6 100644 --- a/packages/typescript-estree/CHANGELOG.md +++ b/packages/typescript-estree/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.1.1](https://github.com/typescript-eslint/typescript-eslint/compare/v4.1.0...v4.1.1) (2020-09-14) + +**Note:** Version bump only for package @typescript-eslint/typescript-estree + + + + + # [4.1.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.0.1...v4.1.0) (2020-09-07) **Note:** Version bump only for package @typescript-eslint/typescript-estree diff --git a/packages/typescript-estree/package.json b/packages/typescript-estree/package.json index ea0874a899c2..68c6fa116b9e 100644 --- a/packages/typescript-estree/package.json +++ b/packages/typescript-estree/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/typescript-estree", - "version": "4.1.0", + "version": "4.1.1", "description": "A parser that converts TypeScript source code into an ESTree compatible form", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -41,8 +41,8 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/types": "4.1.0", - "@typescript-eslint/visitor-keys": "4.1.0", + "@typescript-eslint/types": "4.1.1", + "@typescript-eslint/visitor-keys": "4.1.1", "debug": "^4.1.1", "globby": "^11.0.1", "is-glob": "^4.0.1", @@ -61,7 +61,7 @@ "@types/lodash": "*", "@types/semver": "^7.1.0", "@types/tmp": "^0.2.0", - "@typescript-eslint/shared-fixtures": "4.1.0", + "@typescript-eslint/shared-fixtures": "4.1.1", "glob": "*", "jest-specific-snapshot": "*", "make-dir": "*", diff --git a/packages/visitor-keys/CHANGELOG.md b/packages/visitor-keys/CHANGELOG.md index ef433031f8e3..e360a743ee35 100644 --- a/packages/visitor-keys/CHANGELOG.md +++ b/packages/visitor-keys/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.1.1](https://github.com/typescript-eslint/typescript-eslint/compare/v4.1.0...v4.1.1) (2020-09-14) + +**Note:** Version bump only for package @typescript-eslint/visitor-keys + + + + + # [4.1.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.0.1...v4.1.0) (2020-09-07) **Note:** Version bump only for package @typescript-eslint/visitor-keys diff --git a/packages/visitor-keys/package.json b/packages/visitor-keys/package.json index 4096c33ba645..d7fe215fa5e3 100644 --- a/packages/visitor-keys/package.json +++ b/packages/visitor-keys/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/visitor-keys", - "version": "4.1.0", + "version": "4.1.1", "description": "Visitor keys used to help traverse the TypeScript-ESTree AST", "keywords": [ "eslint", @@ -38,7 +38,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/types": "4.1.0", + "@typescript-eslint/types": "4.1.1", "eslint-visitor-keys": "^2.0.0" }, "devDependencies": {