diff --git a/CHANGELOG.md b/CHANGELOG.md index ec588f1fdaa9..cc5f0e4ea007 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.4.1](https://github.com/typescript-eslint/typescript-eslint/compare/v4.4.0...v4.4.1) (2020-10-12) + + +### Bug Fixes + +* **eslint-plugin:** [ban-ts-comment] support block comments ([#2644](https://github.com/typescript-eslint/typescript-eslint/issues/2644)) ([9c3c686](https://github.com/typescript-eslint/typescript-eslint/commit/9c3c686b59b4b8fd02c479a534b5ca9b33c5ff40)) +* **eslint-plugin:** [ban-types] allow banning types with specific parameters ([#2662](https://github.com/typescript-eslint/typescript-eslint/issues/2662)) ([77732a2](https://github.com/typescript-eslint/typescript-eslint/commit/77732a2f3979f638e471b6de327b2ea0e976d568)) +* **eslint-plugin:** [consistent-type-assertions] check type assertion in jsx props ([#2653](https://github.com/typescript-eslint/typescript-eslint/issues/2653)) ([393e925](https://github.com/typescript-eslint/typescript-eslint/commit/393e92573fbde849369af1d10b9f25299ec92eaf)) +* **eslint-plugin:** [no-duplicate-imports] distinguish member, default ([#2637](https://github.com/typescript-eslint/typescript-eslint/issues/2637)) ([c71f423](https://github.com/typescript-eslint/typescript-eslint/commit/c71f423b89bf034caf2a4f1bb3ed0389b72f3aa9)) +* **eslint-plugin:** [no-throw-literal] false positive with logical expressions ([#2645](https://github.com/typescript-eslint/typescript-eslint/issues/2645)) ([57aa6c7](https://github.com/typescript-eslint/typescript-eslint/commit/57aa6c7642320074ed2b6a15e7f38e66a2fb13d1)) +* **eslint-plugin:** [no-unused-vars] fix false positives for duplicated names in namespaces ([#2659](https://github.com/typescript-eslint/typescript-eslint/issues/2659)) ([0d696c7](https://github.com/typescript-eslint/typescript-eslint/commit/0d696c72c5c9c3446902a63509d499ee95483e81)) +* **eslint-plugin:** [no-use-before-define] correctly handle typeof type references ([#2623](https://github.com/typescript-eslint/typescript-eslint/issues/2623)) ([8e44c78](https://github.com/typescript-eslint/typescript-eslint/commit/8e44c78a20410457851e5b7fe9a24777876c0aaf)) +* **scope-manager:** don't create a variable for global augmentation ([#2639](https://github.com/typescript-eslint/typescript-eslint/issues/2639)) ([6bc9325](https://github.com/typescript-eslint/typescript-eslint/commit/6bc93257ec876214743a165093b6666d713379f6)) + + + + + # [4.4.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.3.0...v4.4.0) (2020-10-05) diff --git a/lerna.json b/lerna.json index 687365c98036..981030f86d25 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "4.4.0", + "version": "4.4.1", "npmClient": "yarn", "useWorkspaces": true, "stream": true diff --git a/packages/eslint-plugin-internal/CHANGELOG.md b/packages/eslint-plugin-internal/CHANGELOG.md index e28fc1b2b222..5e7db3d14399 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.4.1](https://github.com/typescript-eslint/typescript-eslint/compare/v4.4.0...v4.4.1) (2020-10-12) + +**Note:** Version bump only for package @typescript-eslint/eslint-plugin-internal + + + + + # [4.4.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.3.0...v4.4.0) (2020-10-05) **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 9058481419ce..3939dc863eea 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.4.0", + "version": "4.4.1", "private": true, "main": "dist/index.js", "scripts": { @@ -14,7 +14,7 @@ }, "dependencies": { "@types/prettier": "*", - "@typescript-eslint/experimental-utils": "4.4.0", + "@typescript-eslint/experimental-utils": "4.4.1", "prettier": "*" } } diff --git a/packages/eslint-plugin-tslint/CHANGELOG.md b/packages/eslint-plugin-tslint/CHANGELOG.md index c14f19f69019..c6b56ad25795 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.4.1](https://github.com/typescript-eslint/typescript-eslint/compare/v4.4.0...v4.4.1) (2020-10-12) + +**Note:** Version bump only for package @typescript-eslint/eslint-plugin-tslint + + + + + # [4.4.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.3.0...v4.4.0) (2020-10-05) **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 d15ec2ace7ed..2d51f40326e3 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.4.0", + "version": "4.4.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.4.0", + "@typescript-eslint/experimental-utils": "4.4.1", "lodash": "^4.17.15" }, "peerDependencies": { @@ -48,6 +48,6 @@ }, "devDependencies": { "@types/lodash": "*", - "@typescript-eslint/parser": "4.4.0" + "@typescript-eslint/parser": "4.4.1" } } diff --git a/packages/eslint-plugin/CHANGELOG.md b/packages/eslint-plugin/CHANGELOG.md index 122bd696318c..815426db4e88 100644 --- a/packages/eslint-plugin/CHANGELOG.md +++ b/packages/eslint-plugin/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.4.1](https://github.com/typescript-eslint/typescript-eslint/compare/v4.4.0...v4.4.1) (2020-10-12) + + +### Bug Fixes + +* **eslint-plugin:** [ban-ts-comment] support block comments ([#2644](https://github.com/typescript-eslint/typescript-eslint/issues/2644)) ([9c3c686](https://github.com/typescript-eslint/typescript-eslint/commit/9c3c686b59b4b8fd02c479a534b5ca9b33c5ff40)) +* **eslint-plugin:** [ban-types] allow banning types with specific parameters ([#2662](https://github.com/typescript-eslint/typescript-eslint/issues/2662)) ([77732a2](https://github.com/typescript-eslint/typescript-eslint/commit/77732a2f3979f638e471b6de327b2ea0e976d568)) +* **eslint-plugin:** [consistent-type-assertions] check type assertion in jsx props ([#2653](https://github.com/typescript-eslint/typescript-eslint/issues/2653)) ([393e925](https://github.com/typescript-eslint/typescript-eslint/commit/393e92573fbde849369af1d10b9f25299ec92eaf)) +* **eslint-plugin:** [no-duplicate-imports] distinguish member, default ([#2637](https://github.com/typescript-eslint/typescript-eslint/issues/2637)) ([c71f423](https://github.com/typescript-eslint/typescript-eslint/commit/c71f423b89bf034caf2a4f1bb3ed0389b72f3aa9)) +* **eslint-plugin:** [no-throw-literal] false positive with logical expressions ([#2645](https://github.com/typescript-eslint/typescript-eslint/issues/2645)) ([57aa6c7](https://github.com/typescript-eslint/typescript-eslint/commit/57aa6c7642320074ed2b6a15e7f38e66a2fb13d1)) +* **eslint-plugin:** [no-unused-vars] fix false positives for duplicated names in namespaces ([#2659](https://github.com/typescript-eslint/typescript-eslint/issues/2659)) ([0d696c7](https://github.com/typescript-eslint/typescript-eslint/commit/0d696c72c5c9c3446902a63509d499ee95483e81)) +* **eslint-plugin:** [no-use-before-define] correctly handle typeof type references ([#2623](https://github.com/typescript-eslint/typescript-eslint/issues/2623)) ([8e44c78](https://github.com/typescript-eslint/typescript-eslint/commit/8e44c78a20410457851e5b7fe9a24777876c0aaf)) +* **scope-manager:** don't create a variable for global augmentation ([#2639](https://github.com/typescript-eslint/typescript-eslint/issues/2639)) ([6bc9325](https://github.com/typescript-eslint/typescript-eslint/commit/6bc93257ec876214743a165093b6666d713379f6)) + + + + + # [4.4.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.3.0...v4.4.0) (2020-10-05) diff --git a/packages/eslint-plugin/README.md b/packages/eslint-plugin/README.md index 45d6ec7652cc..2f6425bf9028 100644 --- a/packages/eslint-plugin/README.md +++ b/packages/eslint-plugin/README.md @@ -100,7 +100,7 @@ Pro Tip: For larger codebases you may want to consider splitting our linting int | [`@typescript-eslint/adjacent-overload-signatures`](./docs/rules/adjacent-overload-signatures.md) | Require that member overloads be consecutive | :heavy_check_mark: | | | | [`@typescript-eslint/array-type`](./docs/rules/array-type.md) | Requires using either `T[]` or `Array` for arrays | | :wrench: | | | [`@typescript-eslint/await-thenable`](./docs/rules/await-thenable.md) | Disallows awaiting a value that is not a Thenable | :heavy_check_mark: | | :thought_balloon: | -| [`@typescript-eslint/ban-ts-comment`](./docs/rules/ban-ts-comment.md) | Bans `// @ts-` comments from being used or requires descriptions after directive | :heavy_check_mark: | | | +| [`@typescript-eslint/ban-ts-comment`](./docs/rules/ban-ts-comment.md) | Bans `@ts-` comments from being used or requires descriptions after directive | :heavy_check_mark: | | | | [`@typescript-eslint/ban-tslint-comment`](./docs/rules/ban-tslint-comment.md) | Bans `// tslint:` comments from being used | | :wrench: | | | [`@typescript-eslint/ban-types`](./docs/rules/ban-types.md) | Bans specific types from being used | :heavy_check_mark: | :wrench: | | | [`@typescript-eslint/class-literal-property-style`](./docs/rules/class-literal-property-style.md) | Ensures that literals on classes are exposed in a consistent style | | :wrench: | | diff --git a/packages/eslint-plugin/docs/rules/ban-ts-comment.md b/packages/eslint-plugin/docs/rules/ban-ts-comment.md index 2509793ebd37..bfdd4104751d 100644 --- a/packages/eslint-plugin/docs/rules/ban-ts-comment.md +++ b/packages/eslint-plugin/docs/rules/ban-ts-comment.md @@ -1,4 +1,4 @@ -# Bans `// @ts-` comments from being used or requires descriptions after directive (`ban-ts-comment`) +# Bans `@ts-` comments from being used or requires descriptions after directive (`ban-ts-comment`) TypeScript provides several directive comments that can be used to alter how it processes files. Using these to suppress TypeScript Compiler Errors reduces the effectiveness of TypeScript overall. @@ -41,13 +41,19 @@ const defaultOptions: Options = { A value of `true` for a particular directive means that this rule will report if it finds any usage of said directive. -For example, with the defaults above the following patterns are considered warnings: +For example, with the defaults above the following patterns are considered warnings for single line or comment block lines: ```ts if (false) { // @ts-ignore: Unreachable code error console.log('hello'); } +if (false) { + /* + @ts-ignore: Unreachable code error + */ + console.log('hello'); +} ``` The following patterns are not warnings: @@ -63,22 +69,32 @@ if (false) { A value of `'allow-with-description'` for a particular directive means that this rule will report if it finds a directive that does not have a description following the directive (on the same line). -For example, with `{ 'ts-expect-error': 'allow-with-description' }` the following pattern is considered a warning: +For example, with `{ 'ts-expect-error': 'allow-with-description' }` the following patterns are considered a warning: ```ts if (false) { // @ts-expect-error console.log('hello'); } +if (false) { + /* @ts-expect-error */ + console.log('hello'); +} ``` -The following pattern is not a warning: +The following patterns are not a warning: ```ts if (false) { // @ts-expect-error: Unreachable code error console.log('hello'); } +if (false) { + /* + @ts-expect-error: Unreachable code error + */ + console.log('hello'); +} ``` ### `minimumDescriptionLength` diff --git a/packages/eslint-plugin/docs/rules/consistent-type-assertions.md b/packages/eslint-plugin/docs/rules/consistent-type-assertions.md index 43e67b755b52..899647636cb6 100644 --- a/packages/eslint-plugin/docs/rules/consistent-type-assertions.md +++ b/packages/eslint-plugin/docs/rules/consistent-type-assertions.md @@ -74,13 +74,14 @@ function foo(): T { Examples of **correct** code for `{ assertionStyle: 'as', objectLiteralTypeAssertions: 'allow-as-parameter' }`. -```ts +```tsx const x: T = { ... }; const y = { ... } as any; const z = { ... } as unknown; foo({ ... } as T); new Clazz({ ... } as T); function foo() { throw { bar: 5 } as Foo } +const foo = ; ``` ## When Not To Use It diff --git a/packages/eslint-plugin/docs/rules/explicit-function-return-type.md b/packages/eslint-plugin/docs/rules/explicit-function-return-type.md index 9e5b4c841bf2..894a99617532 100644 --- a/packages/eslint-plugin/docs/rules/explicit-function-return-type.md +++ b/packages/eslint-plugin/docs/rules/explicit-function-return-type.md @@ -80,7 +80,7 @@ const defaults = { allowTypedFunctionExpressions: true, allowHigherOrderFunctions: true, allowDirectConstAssertionInArrowFunctions: true, - allowConciseArrowFunctionExpressionsStartingWithVoid: true, + allowConciseArrowFunctionExpressionsStartingWithVoid: false, }; ``` diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 53de6f9fefaa..d520fd7c54b1 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin", - "version": "4.4.0", + "version": "4.4.1", "description": "TypeScript plugin for ESLint", "keywords": [ "eslint", @@ -42,8 +42,8 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/experimental-utils": "4.4.0", - "@typescript-eslint/scope-manager": "4.4.0", + "@typescript-eslint/experimental-utils": "4.4.1", + "@typescript-eslint/scope-manager": "4.4.1", "debug": "^4.1.1", "functional-red-black-tree": "^1.0.1", "regexpp": "^3.0.0", diff --git a/packages/eslint-plugin/src/rules/ban-ts-comment.ts b/packages/eslint-plugin/src/rules/ban-ts-comment.ts index f8c688415987..7c2f237cd4cf 100644 --- a/packages/eslint-plugin/src/rules/ban-ts-comment.ts +++ b/packages/eslint-plugin/src/rules/ban-ts-comment.ts @@ -21,15 +21,15 @@ export default util.createRule<[Options], MessageIds>({ type: 'problem', docs: { description: - 'Bans `// @ts-` comments from being used or requires descriptions after directive', + 'Bans `@ts-` comments from being used or requires descriptions after directive', category: 'Best Practices', recommended: 'error', }, messages: { tsDirectiveComment: - 'Do not use "// @ts-{{directive}}" because it alters compilation errors.', + 'Do not use "@ts-{{directive}}" because it alters compilation errors.', tsDirectiveCommentRequiresDescription: - 'Include a description after the "// @ts-{{directive}}" directive to explain why the @ts-{{directive}} is necessary. The description must be {{minimumDescriptionLength}} characters or longer.', + 'Include a description after the "@ts-{{directive}}" directive to explain why the @ts-{{directive}} is necessary. The description must be {{minimumDescriptionLength}} characters or longer.', }, schema: [ { @@ -98,7 +98,12 @@ export default util.createRule<[Options], MessageIds>({ }, ], create(context, [options]) { - const tsCommentRegExp = /^\/*\s*@ts-(expect-error|ignore|check|nocheck)(.*)/; + /* + The regex used are taken from the ones used in the official TypeScript repo - + https://github.com/microsoft/TypeScript/blob/master/src/compiler/scanner.ts#L281-L289 + */ + const commentDirectiveRegExSingleLine = /^\/*\s*@ts-(expect-error|ignore|check|nocheck)(.*)/; + const commentDirectiveRegExMultiLine = /^\s*(?:\/|\*)*\s*@ts-(expect-error|ignore|check|nocheck)(.*)/; const sourceCode = context.getSourceCode(); return { @@ -106,12 +111,12 @@ export default util.createRule<[Options], MessageIds>({ const comments = sourceCode.getAllComments(); comments.forEach(comment => { + let regExp = commentDirectiveRegExSingleLine; + if (comment.type !== AST_TOKEN_TYPES.Line) { - return; + regExp = commentDirectiveRegExMultiLine; } - - const [, directive, description] = - tsCommentRegExp.exec(comment.value) ?? []; + const [, directive, description] = regExp.exec(comment.value) ?? []; const fullDirective = `ts-${directive}` as keyof Options; diff --git a/packages/eslint-plugin/src/rules/ban-types.ts b/packages/eslint-plugin/src/rules/ban-types.ts index 5ece1b8b60e7..beaadb14ec29 100644 --- a/packages/eslint-plugin/src/rules/ban-types.ts +++ b/packages/eslint-plugin/src/rules/ban-types.ts @@ -28,7 +28,7 @@ function removeSpaces(str: string): string { return str.replace(/ /g, ''); } -function stringifyTypeName( +function stringifyNode( node: TSESTree.Node, sourceCode: TSESLint.SourceCode, ): string { @@ -175,7 +175,7 @@ export default util.createRule({ function checkBannedTypes( typeNode: TSESTree.Node, - name = stringifyTypeName(typeNode, context.getSourceCode()), + name = stringifyNode(typeNode, context.getSourceCode()), ): void { const bannedType = bannedTypes.get(name); @@ -223,8 +223,12 @@ export default util.createRule({ checkBannedTypes(node); }, - TSTypeReference({ typeName }): void { - checkBannedTypes(typeName); + TSTypeReference(node): void { + checkBannedTypes(node.typeName); + + if (node.typeParameters) { + checkBannedTypes(node); + } }, }; }, diff --git a/packages/eslint-plugin/src/rules/consistent-type-assertions.ts b/packages/eslint-plugin/src/rules/consistent-type-assertions.ts index adc88dc965ae..3b431b80675c 100644 --- a/packages/eslint-plugin/src/rules/consistent-type-assertions.ts +++ b/packages/eslint-plugin/src/rules/consistent-type-assertions.ts @@ -140,7 +140,8 @@ export default util.createRule({ (node.parent.type === AST_NODE_TYPES.NewExpression || node.parent.type === AST_NODE_TYPES.CallExpression || node.parent.type === AST_NODE_TYPES.ThrowStatement || - node.parent.type === AST_NODE_TYPES.AssignmentPattern) + node.parent.type === AST_NODE_TYPES.AssignmentPattern || + node.parent.type === AST_NODE_TYPES.JSXExpressionContainer) ) { return; } diff --git a/packages/eslint-plugin/src/rules/no-duplicate-imports.ts b/packages/eslint-plugin/src/rules/no-duplicate-imports.ts index d539845746f7..a6f368902e38 100644 --- a/packages/eslint-plugin/src/rules/no-duplicate-imports.ts +++ b/packages/eslint-plugin/src/rules/no-duplicate-imports.ts @@ -35,7 +35,8 @@ export default util.createRule({ create(context, [option]) { const rules = baseRule.create(context); const includeExports = option.includeExports; - const typeImports = new Set(); + const typeMemberImports = new Set(); + const typeDefaultImports = new Set(); const typeExports = new Set(); function report( @@ -62,16 +63,32 @@ export default util.createRule({ ); } + function isAllMemberImport(node: TSESTree.ImportDeclaration): boolean { + return node.specifiers.every( + specifier => specifier.type === AST_NODE_TYPES.ImportSpecifier, + ); + } + function checkTypeImport(node: TSESTree.ImportDeclaration): void { if (isStringLiteral(node.source)) { const value = node.source.value; - if (typeImports.has(value)) { + const isMemberImport = isAllMemberImport(node); + if ( + isMemberImport + ? typeMemberImports.has(value) + : typeDefaultImports.has(value) + ) { report('importType', node, value); } + if (includeExports && typeExports.has(value)) { report('importTypeAs', node, value); } - typeImports.add(value); + if (isMemberImport) { + typeMemberImports.add(value); + } else { + typeDefaultImports.add(value); + } } } @@ -83,7 +100,7 @@ export default util.createRule({ if (typeExports.has(value)) { report('exportType', node, value); } - if (typeImports.has(value)) { + if (typeMemberImports.has(value) || typeDefaultImports.has(value)) { report('exportTypeAs', node, value); } typeExports.add(value); diff --git a/packages/eslint-plugin/src/rules/no-throw-literal.ts b/packages/eslint-plugin/src/rules/no-throw-literal.ts index b8017c4483a0..acaa4adf9878 100644 --- a/packages/eslint-plugin/src/rules/no-throw-literal.ts +++ b/packages/eslint-plugin/src/rules/no-throw-literal.ts @@ -61,40 +61,6 @@ export default util.createRule({ return false; } - function tryGetThrowArgumentType(node: TSESTree.Node): ts.Type | null { - switch (node.type) { - case AST_NODE_TYPES.Identifier: - case AST_NODE_TYPES.CallExpression: - case AST_NODE_TYPES.NewExpression: - case AST_NODE_TYPES.MemberExpression: - case AST_NODE_TYPES.TSAsExpression: { - const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node); - return checker.getTypeAtLocation(tsNode); - } - - case AST_NODE_TYPES.AssignmentExpression: - return tryGetThrowArgumentType(node.right); - - case AST_NODE_TYPES.SequenceExpression: - return tryGetThrowArgumentType( - node.expressions[node.expressions.length - 1], - ); - - case AST_NODE_TYPES.LogicalExpression: { - const left = tryGetThrowArgumentType(node.left); - return left ?? tryGetThrowArgumentType(node.right); - } - - case AST_NODE_TYPES.ConditionalExpression: { - const consequent = tryGetThrowArgumentType(node.consequent); - return consequent ?? tryGetThrowArgumentType(node.alternate); - } - - default: - return null; - } - } - function checkThrowArgument(node: TSESTree.Node): void { if ( node.type === AST_NODE_TYPES.AwaitExpression || @@ -103,20 +69,20 @@ export default util.createRule({ return; } - const type = tryGetThrowArgumentType(node); - if (type) { - if (type.flags & ts.TypeFlags.Undefined) { - context.report({ node, messageId: 'undef' }); - return; - } + const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node); + const type = checker.getTypeAtLocation(tsNode); - if ( - util.isTypeAnyType(type) || - util.isTypeUnknownType(type) || - isErrorLike(type) - ) { - return; - } + if (type.flags & ts.TypeFlags.Undefined) { + context.report({ node, messageId: 'undef' }); + return; + } + + if ( + util.isTypeAnyType(type) || + util.isTypeUnknownType(type) || + isErrorLike(type) + ) { + return; } context.report({ node, messageId: 'object' }); diff --git a/packages/eslint-plugin/src/rules/no-unused-vars.ts b/packages/eslint-plugin/src/rules/no-unused-vars.ts index 7239982c9356..8753452dd097 100644 --- a/packages/eslint-plugin/src/rules/no-unused-vars.ts +++ b/packages/eslint-plugin/src/rules/no-unused-vars.ts @@ -1,7 +1,7 @@ import { - TSESTree, - TSESLint, AST_NODE_TYPES, + TSESLint, + TSESTree, } from '@typescript-eslint/experimental-utils'; import { PatternVisitor } from '@typescript-eslint/scope-manager'; import baseRule from 'eslint/lib/rules/no-unused-vars'; @@ -327,18 +327,22 @@ export default util.createRule({ break; } - const scope = context.getScope(); - const { variableScope } = scope; - if (variableScope !== scope) { - for (const id of identifiers) { - const superVar = variableScope.set.get(id.name); - if (superVar) { - superVar.eslintUsed = true; - } - } - } else { - for (const id of identifiers) { - context.markVariableAsUsed(id.name); + let scope = context.getScope(); + const shouldUseUpperScope = [ + AST_NODE_TYPES.TSModuleDeclaration, + AST_NODE_TYPES.TSDeclareFunction, + ].includes(node.type); + + if (scope.variableScope !== scope) { + scope = scope.variableScope; + } else if (shouldUseUpperScope && scope.upper) { + scope = scope.upper; + } + + for (const id of identifiers) { + const superVar = scope.set.get(id.name); + if (superVar) { + superVar.eslintUsed = true; } } } 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 18525a138ced..b67f5ef09c33 100644 --- a/packages/eslint-plugin/src/rules/no-use-before-define.ts +++ b/packages/eslint-plugin/src/rules/no-use-before-define.ts @@ -92,6 +92,37 @@ function isOuterVariable( ); } +/** + * Recursively checks whether or not a given reference has a type query declaration among it's parents + */ +function referenceContainsTypeQuery(node: TSESTree.Node): boolean { + switch (node.type) { + case AST_NODE_TYPES.TSTypeQuery: + return true; + + case AST_NODE_TYPES.TSQualifiedName: + case AST_NODE_TYPES.Identifier: + if (!node.parent) { + return false; + } + return referenceContainsTypeQuery(node.parent); + + default: + // if we find a different node, there's no chance that we're in a TSTypeQuery + return false; + } +} + +/** + * Checks whether or not a given reference is a type reference. + */ +function isTypeReference(reference: TSESLint.Scope.Reference): boolean { + return ( + reference.isTypeReference || + referenceContainsTypeQuery(reference.identifier) + ); +} + /** * Checks whether or not a given location is inside of the range of a given node. */ @@ -219,7 +250,7 @@ export default util.createRule({ variable: TSESLint.Scope.Variable, reference: TSESLint.Scope.Reference, ): boolean { - if (reference.isTypeReference && options.ignoreTypeReferences) { + if (options.ignoreTypeReferences && isTypeReference(reference)) { return false; } if (isFunction(variable)) { diff --git a/packages/eslint-plugin/tests/rules/ban-ts-comment.test.ts b/packages/eslint-plugin/tests/rules/ban-ts-comment.test.ts index 2d59e1b315a9..994da016d5f7 100644 --- a/packages/eslint-plugin/tests/rules/ban-ts-comment.test.ts +++ b/packages/eslint-plugin/tests/rules/ban-ts-comment.test.ts @@ -8,11 +8,9 @@ const ruleTester = new RuleTester({ ruleTester.run('ts-expect-error', rule, { valid: [ '// just a comment containing @ts-expect-error somewhere', - '/* @ts-expect-error */', - '/** @ts-expect-error */', ` /* -// @ts-expect-error in a block + @ts-expect-error running with long description in a block */ `, { @@ -50,6 +48,46 @@ ruleTester.run('ts-expect-error', rule, { }, ], }, + { + code: '/* @ts-expect-error */', + options: [{ 'ts-expect-error': true }], + errors: [ + { + data: { directive: 'expect-error' }, + messageId: 'tsDirectiveComment', + line: 1, + column: 1, + }, + ], + }, + { + code: ` +/* +@ts-expect-error +*/ + `, + options: [{ 'ts-expect-error': true }], + errors: [ + { + data: { directive: 'expect-error' }, + messageId: 'tsDirectiveComment', + line: 2, + column: 1, + }, + ], + }, + { + code: '/** @ts-expect-error */', + options: [{ 'ts-expect-error': true }], + errors: [ + { + data: { directive: 'expect-error' }, + messageId: 'tsDirectiveComment', + line: 1, + column: 1, + }, + ], + }, { code: '// @ts-expect-error: Suppress next line', options: [{ 'ts-expect-error': true }], @@ -130,13 +168,6 @@ if (false) { ruleTester.run('ts-ignore', rule, { valid: [ '// just a comment containing @ts-ignore somewhere', - '/* @ts-ignore */', - '/** @ts-ignore */', - ` -/* -// @ts-ignore in a block -*/ - `, { code: '// @ts-ignore', options: [{ 'ts-ignore': false }], @@ -146,6 +177,19 @@ ruleTester.run('ts-ignore', rule, { '// @ts-ignore I think that I am exempted from any need to follow the rules!', options: [{ 'ts-ignore': 'allow-with-description' }], }, + { + code: ` +/* + @ts-ignore running with long description in a block +*/ + `, + options: [ + { + 'ts-ignore': 'allow-with-description', + minimumDescriptionLength: 21, + }, + ], + }, ], invalid: [ { @@ -171,6 +215,46 @@ ruleTester.run('ts-ignore', rule, { }, ], }, + { + code: '/* @ts-ignore */', + options: [{ 'ts-ignore': true }], + errors: [ + { + data: { directive: 'ignore' }, + messageId: 'tsDirectiveComment', + line: 1, + column: 1, + }, + ], + }, + { + code: ` +/* + @ts-ignore +*/ + `, + options: [{ 'ts-ignore': true }], + errors: [ + { + data: { directive: 'ignore' }, + messageId: 'tsDirectiveComment', + line: 2, + column: 1, + }, + ], + }, + { + code: '/** @ts-ignore */', + options: [{ 'ts-ignore': true }], + errors: [ + { + data: { directive: 'ignore' }, + messageId: 'tsDirectiveComment', + line: 1, + column: 1, + }, + ], + }, { code: '// @ts-ignore: Suppress next line', errors: [ @@ -251,13 +335,6 @@ if (false) { ruleTester.run('ts-nocheck', rule, { valid: [ '// just a comment containing @ts-nocheck somewhere', - '/* @ts-nocheck */', - '/** @ts-nocheck */', - ` -/* -// @ts-nocheck in a block -*/ - `, { code: '// @ts-nocheck', options: [{ 'ts-nocheck': false }], @@ -267,6 +344,19 @@ ruleTester.run('ts-nocheck', rule, { '// @ts-nocheck no doubt, people will put nonsense here from time to time just to get the rule to stop reporting, perhaps even long messages with other nonsense in them like other // @ts-nocheck or // @ts-ignore things', options: [{ 'ts-nocheck': 'allow-with-description' }], }, + { + code: ` +/* + @ts-nocheck running with long description in a block +*/ + `, + options: [ + { + 'ts-nocheck': 'allow-with-description', + minimumDescriptionLength: 21, + }, + ], + }, ], invalid: [ { @@ -292,6 +382,46 @@ ruleTester.run('ts-nocheck', rule, { }, ], }, + { + code: '/* @ts-nocheck */', + options: [{ 'ts-nocheck': true }], + errors: [ + { + data: { directive: 'nocheck' }, + messageId: 'tsDirectiveComment', + line: 1, + column: 1, + }, + ], + }, + { + code: ` +/* + @ts-nocheck +*/ + `, + options: [{ 'ts-nocheck': true }], + errors: [ + { + data: { directive: 'nocheck' }, + messageId: 'tsDirectiveComment', + line: 2, + column: 1, + }, + ], + }, + { + code: '/** @ts-nocheck */', + options: [{ 'ts-nocheck': true }], + errors: [ + { + data: { directive: 'nocheck' }, + messageId: 'tsDirectiveComment', + line: 1, + column: 1, + }, + ], + }, { code: '// @ts-nocheck: Suppress next line', errors: [ @@ -348,11 +478,9 @@ if (false) { ruleTester.run('ts-check', rule, { valid: [ '// just a comment containing @ts-check somewhere', - '/* @ts-check */', - '/** @ts-check */', ` /* -// @ts-check in a block + @ts-check running with long description in a block */ `, { @@ -380,6 +508,46 @@ ruleTester.run('ts-check', rule, { }, ], }, + { + code: '/* @ts-check */', + options: [{ 'ts-check': true }], + errors: [ + { + data: { directive: 'check' }, + messageId: 'tsDirectiveComment', + line: 1, + column: 1, + }, + ], + }, + { + code: ` +/* + @ts-check +*/ + `, + options: [{ 'ts-check': true }], + errors: [ + { + data: { directive: 'check' }, + messageId: 'tsDirectiveComment', + line: 2, + column: 1, + }, + ], + }, + { + code: '/** @ts-check */', + options: [{ 'ts-check': true }], + errors: [ + { + data: { directive: 'check' }, + messageId: 'tsDirectiveComment', + line: 1, + column: 1, + }, + ], + }, { code: '// @ts-check: Suppress next line', options: [{ 'ts-check': true }], diff --git a/packages/eslint-plugin/tests/rules/ban-types.test.ts b/packages/eslint-plugin/tests/rules/ban-types.test.ts index 615c3f3dc000..ca7078585b13 100644 --- a/packages/eslint-plugin/tests/rules/ban-types.test.ts +++ b/packages/eslint-plugin/tests/rules/ban-types.test.ts @@ -487,6 +487,48 @@ let bar: object = {}; }, ], }, + { + code: 'type Foo = Bar;', + errors: [ + { + messageId: 'bannedTypeMessage', + data: { + name: 'Bar', + customMessage: " Don't use `any` as a type parameter to `Bar`", + }, + line: 1, + column: 12, + }, + ], + options: [ + { + types: { + 'Bar': "Don't use `any` as a type parameter to `Bar`", + }, + }, + ], + }, + { + code: noFormat`type Foo = Bar;`, + errors: [ + { + messageId: 'bannedTypeMessage', + data: { + name: 'Bar', + customMessage: " Don't pass `A, B` as parameters to `Bar`", + }, + line: 1, + column: 12, + }, + ], + options: [ + { + types: { + 'Bar': "Don't pass `A, B` as parameters to `Bar`", + }, + }, + ], + }, ...objectReduceKey( TYPE_KEYWORDS, (acc: TSESLint.InvalidTestCase[], key) => { diff --git a/packages/eslint-plugin/tests/rules/consistent-type-assertions.test.ts b/packages/eslint-plugin/tests/rules/consistent-type-assertions.test.ts index 010bb894ad7a..1711e4450c38 100644 --- a/packages/eslint-plugin/tests/rules/consistent-type-assertions.test.ts +++ b/packages/eslint-plugin/tests/rules/consistent-type-assertions.test.ts @@ -112,6 +112,20 @@ ruleTester.run('consistent-type-assertions', rule, { }, ], }, + { + code: 'const bar = ;', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + options: [ + { + assertionStyle: 'as', + objectLiteralTypeAssertions: 'allow-as-parameter', + }, + ], + }, ], invalid: [ ...batchedSingleLineTests({ @@ -342,5 +356,24 @@ ruleTester.run('consistent-type-assertions', rule, { }, ], }), + { + code: 'const foo = ;', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + options: [ + { + assertionStyle: 'never', + }, + ], + errors: [ + { + messageId: 'never', + line: 1, + }, + ], + }, ], }); diff --git a/packages/eslint-plugin/tests/rules/no-duplicate-imports.test.ts b/packages/eslint-plugin/tests/rules/no-duplicate-imports.test.ts index d133a7aadd9e..98e12fbeb7a8 100644 --- a/packages/eslint-plugin/tests/rules/no-duplicate-imports.test.ts +++ b/packages/eslint-plugin/tests/rules/no-duplicate-imports.test.ts @@ -5,7 +5,7 @@ const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', }); -ruleTester.run('no-dupe-class-members', rule, { +ruleTester.run('no-duplicate-imports', rule, { valid: [ { code: "import type foo from 'foo';", @@ -13,6 +13,24 @@ ruleTester.run('no-dupe-class-members', rule, { { code: "import type { foo } from 'foo';", }, + { + code: ` + import type { foo } from 'foo'; + import type Bar from 'foo'; + `, + }, + { + code: ` + import type Foo from 'foo'; + import type { bar } from 'foo'; + `, + }, + { + code: ` + import type Foo from 'foo'; + import type { bar as Bar } from 'foo'; + `, + }, { code: ` import foo from 'foo'; @@ -69,6 +87,14 @@ ruleTester.run('no-dupe-class-members', rule, { `, options: [{ includeExports: true }], }, + { + code: ` + import type Foo from 'foo'; + import type { bar } from 'foo'; + export type { bar }; + `, + options: [{ includeExports: true }], + }, ], invalid: [ { @@ -116,6 +142,15 @@ ruleTester.run('no-dupe-class-members', rule, { options: [{ includeExports: true }], errors: [{ messageId: 'exportTypeAs' }], }, + { + code: ` + import type Foo from 'foo'; + import type { bar } from 'foo'; + export type { bar } from 'foo'; + `, + options: [{ includeExports: true }], + errors: [{ messageId: 'exportTypeAs' }], + }, { code: ` export type * as foo from 'foo'; diff --git a/packages/eslint-plugin/tests/rules/no-throw-literal.test.ts b/packages/eslint-plugin/tests/rules/no-throw-literal.test.ts index 883894bf2a1c..c8ee6e3eb9ca 100644 --- a/packages/eslint-plugin/tests/rules/no-throw-literal.test.ts +++ b/packages/eslint-plugin/tests/rules/no-throw-literal.test.ts @@ -61,14 +61,13 @@ throw new CustomError(); ` class CustomError1 extends Error {} class CustomError2 extends CustomError1 {} -throw new CustomError(); +throw new CustomError2(); `, 'throw (foo = new Error());', 'throw (1, 2, new Error());', "throw 'literal' && new Error();", "throw new Error() || 'literal';", - "throw foo ? new Error() : 'literal';", - "throw foo ? 'literal' : new Error();", + 'throw foo ? new Error() : new Error();', ` function* foo() { let index = 0; @@ -112,6 +111,18 @@ declare const foo: Error | string; throw foo as Error; `, 'throw new Error() as Error;', + ` +declare const nullishError: Error | undefined; +throw nullishError ?? new Error(); + `, + ` +declare const nullishError: Error | undefined; +throw nullishError || new Error(); + `, + ` +declare const nullishError: Error | undefined; +throw nullishError ? nullishError : new Error(); + `, ], invalid: [ { @@ -207,19 +218,31 @@ throw a + 'b'; }, { code: "throw 'literal' && 'not an Error';", - errors: [ - { - messageId: 'object', - }, - ], + errors: [{ messageId: 'object' }], + }, + { + code: "throw 'literal' || new Error();", + errors: [{ messageId: 'object' }], + }, + { + code: "throw new Error() && 'literal';", + errors: [{ messageId: 'object' }], + }, + { + code: "throw 'literal' ?? new Error();", + errors: [{ messageId: 'object' }], }, { code: "throw foo ? 'not an Error' : 'literal';", - errors: [ - { - messageId: 'object', - }, - ], + errors: [{ messageId: 'object' }], + }, + { + code: "throw foo ? new Error() : 'literal';", + errors: [{ messageId: 'object' }], + }, + { + code: "throw foo ? 'literal' : new Error();", + errors: [{ messageId: 'object' }], }, { code: 'throw `${err}`;', 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 e22f9eb2ba7c..b3d9c92491d2 100644 --- a/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts @@ -886,6 +886,20 @@ export declare namespace Foo { } } `, + { + code: ` +declare namespace A { + export interface A {} +} + `, + filename: 'foo.d.ts', + }, + { + code: ` +declare function A(A: string): string; + `, + filename: 'foo.d.ts', + }, ], invalid: [ 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 ad66ff7858e5..77e434d33821 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 @@ -219,7 +219,43 @@ type Foo = string | number; `, options: [{ typedefs: false }], }, + // https://github.com/typescript-eslint/typescript-eslint/issues/2572 + { + code: ` +interface Bar { + type: typeof Foo; +} + +const Foo = 2; + `, + options: [{ ignoreTypeReferences: true }], + }, + { + code: ` +interface Bar { + type: typeof Foo.FOO; +} +class Foo { + public static readonly FOO = ''; +} + `, + options: [{ ignoreTypeReferences: true }], + }, + { + code: ` +interface Bar { + type: typeof Foo.Bar.Baz; +} + +const Foo = { + Bar: { + Baz: 1, + }, +}; + `, + options: [{ ignoreTypeReferences: true }], + }, // https://github.com/bradzacher/eslint-plugin-typescript/issues/141 { code: ` @@ -347,6 +383,17 @@ const React = require('react'); ` type T = (value: unknown) => value is Id; `, + ` +global.foo = true; + +declare global { + namespace NodeJS { + interface Global { + foo?: boolean; + } + } +} + `, ], invalid: [ { @@ -864,6 +911,65 @@ for (var a of a) { ], }, + // "ignoreTypeReferences" option + { + code: ` +interface Bar { + type: typeof Foo; +} + +const Foo = 2; + `, + options: [{ ignoreTypeReferences: false }], + errors: [ + { + messageId: 'noUseBeforeDefine', + data: { name: 'Foo' }, + type: AST_NODE_TYPES.Identifier, + }, + ], + }, + { + code: ` +interface Bar { + type: typeof Foo.FOO; +} + +class Foo { + public static readonly FOO = ''; +} + `, + options: [{ ignoreTypeReferences: false }], + errors: [ + { + messageId: 'noUseBeforeDefine', + data: { name: 'Foo' }, + type: AST_NODE_TYPES.Identifier, + }, + ], + }, + { + code: ` +interface Bar { + type: typeof Foo.Bar.Baz; +} + +const Foo = { + Bar: { + Baz: 1, + }, +}; + `, + options: [{ ignoreTypeReferences: false }], + errors: [ + { + messageId: 'noUseBeforeDefine', + data: { name: 'Foo' }, + type: AST_NODE_TYPES.Identifier, + }, + ], + }, + // "variables" option { code: ` diff --git a/packages/experimental-utils/CHANGELOG.md b/packages/experimental-utils/CHANGELOG.md index 91cd1ad40a0c..f3d4ce8cc45e 100644 --- a/packages/experimental-utils/CHANGELOG.md +++ b/packages/experimental-utils/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.4.1](https://github.com/typescript-eslint/typescript-eslint/compare/v4.4.0...v4.4.1) (2020-10-12) + +**Note:** Version bump only for package @typescript-eslint/experimental-utils + + + + + # [4.4.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.3.0...v4.4.0) (2020-10-05) **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 e91a2baf3f23..3f3e87e0072b 100644 --- a/packages/experimental-utils/package.json +++ b/packages/experimental-utils/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/experimental-utils", - "version": "4.4.0", + "version": "4.4.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.4.0", - "@typescript-eslint/types": "4.4.0", - "@typescript-eslint/typescript-estree": "4.4.0", + "@typescript-eslint/scope-manager": "4.4.1", + "@typescript-eslint/types": "4.4.1", + "@typescript-eslint/typescript-estree": "4.4.1", "eslint-scope": "^5.0.0", "eslint-utils": "^2.0.0" }, diff --git a/packages/parser/CHANGELOG.md b/packages/parser/CHANGELOG.md index 1592b404d7f9..8cf3b5f7c1f3 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.4.1](https://github.com/typescript-eslint/typescript-eslint/compare/v4.4.0...v4.4.1) (2020-10-12) + +**Note:** Version bump only for package @typescript-eslint/parser + + + + + # [4.4.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.3.0...v4.4.0) (2020-10-05) **Note:** Version bump only for package @typescript-eslint/parser diff --git a/packages/parser/package.json b/packages/parser/package.json index 7b383e493fdf..97369211c18f 100644 --- a/packages/parser/package.json +++ b/packages/parser/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/parser", - "version": "4.4.0", + "version": "4.4.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.4.0", - "@typescript-eslint/types": "4.4.0", - "@typescript-eslint/typescript-estree": "4.4.0", + "@typescript-eslint/scope-manager": "4.4.1", + "@typescript-eslint/types": "4.4.1", + "@typescript-eslint/typescript-estree": "4.4.1", "debug": "^4.1.1" }, "devDependencies": { "@types/glob": "*", - "@typescript-eslint/experimental-utils": "4.4.0", - "@typescript-eslint/shared-fixtures": "4.4.0", + "@typescript-eslint/experimental-utils": "4.4.1", + "@typescript-eslint/shared-fixtures": "4.4.1", "glob": "*", "typescript": "*" }, diff --git a/packages/scope-manager/CHANGELOG.md b/packages/scope-manager/CHANGELOG.md index 755f9b9a0920..8541136c8a91 100644 --- a/packages/scope-manager/CHANGELOG.md +++ b/packages/scope-manager/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.4.1](https://github.com/typescript-eslint/typescript-eslint/compare/v4.4.0...v4.4.1) (2020-10-12) + + +### Bug Fixes + +* **scope-manager:** don't create a variable for global augmentation ([#2639](https://github.com/typescript-eslint/typescript-eslint/issues/2639)) ([6bc9325](https://github.com/typescript-eslint/typescript-eslint/commit/6bc93257ec876214743a165093b6666d713379f6)) + + + + + # [4.4.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.3.0...v4.4.0) (2020-10-05) **Note:** Version bump only for package @typescript-eslint/scope-manager diff --git a/packages/scope-manager/package.json b/packages/scope-manager/package.json index 2296fc74278b..dffcd4661fe9 100644 --- a/packages/scope-manager/package.json +++ b/packages/scope-manager/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/scope-manager", - "version": "4.4.0", + "version": "4.4.1", "description": "TypeScript scope analyser for ESLint", "keywords": [ "eslint", @@ -39,12 +39,12 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/types": "4.4.0", - "@typescript-eslint/visitor-keys": "4.4.0" + "@typescript-eslint/types": "4.4.1", + "@typescript-eslint/visitor-keys": "4.4.1" }, "devDependencies": { "@types/glob": "*", - "@typescript-eslint/typescript-estree": "4.4.0", + "@typescript-eslint/typescript-estree": "4.4.1", "glob": "*", "jest-specific-snapshot": "*", "make-dir": "*", diff --git a/packages/scope-manager/src/referencer/Referencer.ts b/packages/scope-manager/src/referencer/Referencer.ts index 6cccab10428c..56c974055bce 100644 --- a/packages/scope-manager/src/referencer/Referencer.ts +++ b/packages/scope-manager/src/referencer/Referencer.ts @@ -765,7 +765,7 @@ class Referencer extends Visitor { } protected TSModuleDeclaration(node: TSESTree.TSModuleDeclaration): void { - if (node.id.type === AST_NODE_TYPES.Identifier) { + if (node.id.type === AST_NODE_TYPES.Identifier && !node.global) { this.currentScope().defineIdentifier( node.id, new TSModuleNameDefinition(node.id, node), diff --git a/packages/scope-manager/tests/fixtures/ts-module/global-augmentation.ts b/packages/scope-manager/tests/fixtures/ts-module/global-augmentation.ts new file mode 100644 index 000000000000..078de28ca2f3 --- /dev/null +++ b/packages/scope-manager/tests/fixtures/ts-module/global-augmentation.ts @@ -0,0 +1,3 @@ +//// @sourceType = module + +declare global {} diff --git a/packages/scope-manager/tests/fixtures/ts-module/global-augmentation.ts.shot b/packages/scope-manager/tests/fixtures/ts-module/global-augmentation.ts.shot new file mode 100644 index 000000000000..4a93b6395457 --- /dev/null +++ b/packages/scope-manager/tests/fixtures/ts-module/global-augmentation.ts.shot @@ -0,0 +1,42 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ts-module global-augmentation 1`] = ` +ScopeManager { + variables: Array [ + ImplicitGlobalConstTypeVariable, + ], + scopes: Array [ + GlobalScope$1 { + block: Program$1, + isStrict: false, + references: Array [], + set: Map { + "const" => ImplicitGlobalConstTypeVariable, + }, + type: "global", + upper: null, + variables: Array [ + ImplicitGlobalConstTypeVariable, + ], + }, + ModuleScope$2 { + block: Program$1, + isStrict: true, + references: Array [], + set: Map {}, + type: "module", + upper: GlobalScope$1, + variables: Array [], + }, + TSModuleScope$3 { + block: TSModuleDeclaration$2, + isStrict: true, + references: Array [], + set: Map {}, + type: "tsModule", + upper: ModuleScope$2, + variables: Array [], + }, + ], +} +`; diff --git a/packages/shared-fixtures/CHANGELOG.md b/packages/shared-fixtures/CHANGELOG.md index c008c2d632d5..0522533017fb 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.4.1](https://github.com/typescript-eslint/typescript-eslint/compare/v4.4.0...v4.4.1) (2020-10-12) + +**Note:** Version bump only for package @typescript-eslint/shared-fixtures + + + + + # [4.4.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.3.0...v4.4.0) (2020-10-05) **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 492a942cbada..a68e53d97ee9 100644 --- a/packages/shared-fixtures/package.json +++ b/packages/shared-fixtures/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/shared-fixtures", - "version": "4.4.0", + "version": "4.4.1", "private": true, "scripts": { "build": "tsc -b tsconfig.build.json", diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md index aa694c4b7f12..04551ba51e83 100644 --- a/packages/types/CHANGELOG.md +++ b/packages/types/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.4.1](https://github.com/typescript-eslint/typescript-eslint/compare/v4.4.0...v4.4.1) (2020-10-12) + +**Note:** Version bump only for package @typescript-eslint/types + + + + + # [4.4.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.3.0...v4.4.0) (2020-10-05) **Note:** Version bump only for package @typescript-eslint/types diff --git a/packages/types/package.json b/packages/types/package.json index 41d6b014b96a..a237687f0bee 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/types", - "version": "4.4.0", + "version": "4.4.1", "description": "Types for the TypeScript-ESTree AST spec", "keywords": [ "eslint", diff --git a/packages/typescript-estree/CHANGELOG.md b/packages/typescript-estree/CHANGELOG.md index 6d2608b31a16..54f7dc5d7562 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.4.1](https://github.com/typescript-eslint/typescript-eslint/compare/v4.4.0...v4.4.1) (2020-10-12) + +**Note:** Version bump only for package @typescript-eslint/typescript-estree + + + + + # [4.4.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.3.0...v4.4.0) (2020-10-05) **Note:** Version bump only for package @typescript-eslint/typescript-estree diff --git a/packages/typescript-estree/README.md b/packages/typescript-estree/README.md index 3a434c784165..4fdbb42dc10d 100644 --- a/packages/typescript-estree/README.md +++ b/packages/typescript-estree/README.md @@ -265,13 +265,7 @@ Please check the current list of open and known issues and ensure the issue has A couple of years after work on this parser began, the TypeScript Team at Microsoft began [officially supporting TypeScript parsing via Babel](https://blogs.msdn.microsoft.com/typescript/2018/08/27/typescript-and-babel-7/). -I work closely with the TypeScript Team and we are gradually aligning the AST of this project with the one produced by Babel's parser. To that end, I have created a full test harness to compare the ASTs of the two projects which runs on every PR, please see the code for more details. - -## Build/Test Commands - -- `npm test` - run all tests -- `npm run unit-tests` - run only unit tests -- `npm run ast-alignment-tests` - run only Babylon AST alignment tests +I work closely with the TypeScript Team and we are gradually aligning the AST of this project with the one produced by Babel's parser. To that end, I have created a full test harness to compare the ASTs of the two projects which runs on every PR, please see [the code](https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/typescript-estree/tests/ast-alignment) for more details. ## Debugging diff --git a/packages/typescript-estree/package.json b/packages/typescript-estree/package.json index 869183a5d000..0b58c7285242 100644 --- a/packages/typescript-estree/package.json +++ b/packages/typescript-estree/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/typescript-estree", - "version": "4.4.0", + "version": "4.4.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.4.0", - "@typescript-eslint/visitor-keys": "4.4.0", + "@typescript-eslint/types": "4.4.1", + "@typescript-eslint/visitor-keys": "4.4.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.4.0", + "@typescript-eslint/shared-fixtures": "4.4.1", "glob": "*", "jest-specific-snapshot": "*", "make-dir": "*", diff --git a/packages/typescript-estree/tests/ast-alignment/parse.ts b/packages/typescript-estree/tests/ast-alignment/parse.ts index 0e24d6842bd8..be37945b3a34 100644 --- a/packages/typescript-estree/tests/ast-alignment/parse.ts +++ b/packages/typescript-estree/tests/ast-alignment/parse.ts @@ -21,18 +21,9 @@ function createError( function parseWithBabelParser(text: string, jsx = true): any { const babel = require('@babel/parser'); const plugins: ParserPlugin[] = [ - 'asyncGenerators', - 'bigInt', 'classProperties', 'decorators-legacy', - 'dynamicImport', 'estree', - 'importMeta', - 'logicalAssignment', - 'nullishCoalescingOperator', - 'numericSeparator', - 'objectRestSpread', - 'optionalChaining', 'typescript', ]; if (jsx) { diff --git a/packages/visitor-keys/CHANGELOG.md b/packages/visitor-keys/CHANGELOG.md index fa0eb27682ce..94dcd91284c2 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.4.1](https://github.com/typescript-eslint/typescript-eslint/compare/v4.4.0...v4.4.1) (2020-10-12) + +**Note:** Version bump only for package @typescript-eslint/visitor-keys + + + + + # [4.4.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.3.0...v4.4.0) (2020-10-05) **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 1efdff1f83bd..184b52e939ac 100644 --- a/packages/visitor-keys/package.json +++ b/packages/visitor-keys/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/visitor-keys", - "version": "4.4.0", + "version": "4.4.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.4.0", + "@typescript-eslint/types": "4.4.1", "eslint-visitor-keys": "^2.0.0" }, "devDependencies": {