From d61ed9df3bfba2f1ce53ca2140302e7edac82bd8 Mon Sep 17 00:00:00 2001 From: phiresky Date: Thu, 11 Jun 2020 01:42:59 +0200 Subject: [PATCH 01/15] feat(typescript-estree): allow catch clause to have a type See https://github.com/microsoft/TypeScript/issues/36775 --- packages/typescript-estree/src/ast-converter.ts | 4 ++-- packages/typescript-estree/src/convert.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/typescript-estree/src/ast-converter.ts b/packages/typescript-estree/src/ast-converter.ts index 36ca1830ccd7..ad3b06dbb513 100644 --- a/packages/typescript-estree/src/ast-converter.ts +++ b/packages/typescript-estree/src/ast-converter.ts @@ -40,10 +40,10 @@ export function astConverter( simpleTraverse(estree, { enter: node => { if (!extra.range) { - delete node.range; + delete (node as any).range; } if (!extra.loc) { - delete node.loc; + delete (node as any).loc; } }, }); diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 2a6db370570b..1881d847fc56 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -697,7 +697,7 @@ export class Converter { return this.createNode(node, { type: AST_NODE_TYPES.CatchClause, param: node.variableDeclaration - ? this.convertChild(node.variableDeclaration.name) + ? this.convertChild(node.variableDeclaration).id : null, body: this.convertChild(node.block), }); From 81fbc88ebae847cb7784746c44a6437441ea820c Mon Sep 17 00:00:00 2001 From: phiresky Date: Thu, 11 Jun 2020 01:43:33 +0200 Subject: [PATCH 02/15] feat(eslint-plugin): add no-implicit-any-catch rule --- packages/eslint-plugin/README.md | 1 + .../docs/rules/no-implicit-any-catch.md | 57 +++++++++++ packages/eslint-plugin/src/configs/all.ts | 1 + .../eslint-plugin/src/configs/recommended.ts | 1 + packages/eslint-plugin/src/rules/index.ts | 2 + .../src/rules/no-implicit-any-catch.ts | 95 +++++++++++++++++++ .../tests/rules/no-implicit-any-catch.test.ts | 73 ++++++++++++++ .../typescript-estree/src/ast-converter.ts | 4 +- 8 files changed, 232 insertions(+), 2 deletions(-) create mode 100644 packages/eslint-plugin/docs/rules/no-implicit-any-catch.md create mode 100644 packages/eslint-plugin/src/rules/no-implicit-any-catch.ts create mode 100644 packages/eslint-plugin/tests/rules/no-implicit-any-catch.test.ts diff --git a/packages/eslint-plugin/README.md b/packages/eslint-plugin/README.md index 5f9822ed12f4..51c0ec1d7fbf 100644 --- a/packages/eslint-plugin/README.md +++ b/packages/eslint-plugin/README.md @@ -122,6 +122,7 @@ Pro Tip: For larger codebases you may want to consider splitting our linting int | [`@typescript-eslint/no-extraneous-class`](./docs/rules/no-extraneous-class.md) | Forbids the use of classes as namespaces | | | | | [`@typescript-eslint/no-floating-promises`](./docs/rules/no-floating-promises.md) | Requires Promise-like values to be handled appropriately | :heavy_check_mark: | | :thought_balloon: | | [`@typescript-eslint/no-for-in-array`](./docs/rules/no-for-in-array.md) | Disallow iterating over an array with a for-in loop | :heavy_check_mark: | | :thought_balloon: | +| [`@typescript-eslint/no-implicit-any-catch`](./docs/rules/no-implicit-any-catch.md) | Disallow usage of the implicit `any` type in catch clauses | :heavy_check_mark: | :wrench: | | | [`@typescript-eslint/no-implied-eval`](./docs/rules/no-implied-eval.md) | Disallow the use of `eval()`-like methods | :heavy_check_mark: | | :thought_balloon: | | [`@typescript-eslint/no-inferrable-types`](./docs/rules/no-inferrable-types.md) | Disallows explicit type declarations for variables or parameters initialized to a number, string, or boolean | :heavy_check_mark: | :wrench: | | | [`@typescript-eslint/no-invalid-void-type`](./docs/rules/no-invalid-void-type.md) | Disallows usage of `void` type outside of generic or return types | | | | diff --git a/packages/eslint-plugin/docs/rules/no-implicit-any-catch.md b/packages/eslint-plugin/docs/rules/no-implicit-any-catch.md new file mode 100644 index 000000000000..11503556d17d --- /dev/null +++ b/packages/eslint-plugin/docs/rules/no-implicit-any-catch.md @@ -0,0 +1,57 @@ +# Disallow usage of the implicit `any` type in catch clauses (`no-implicit-any-catch`) + +Using the `any` type defeats the purpose of using TypeScript. +When `any` is used, all compiler type checks around that value are ignored. + +The noImplicitAny flag in TypeScript does not cover this due to backwards compatibility reasons. + +## Rule Details + +This rule doesn't requires an explicit type to be declared in the catch clause error argument. + +The following pattern is considered a warning: + +```ts +try { + // ... +} catch (e) { + // ... +} +``` + +The following patterns are not warnings: + +```ts +try { + // ... +} catch (e) { + // ... +} +``` + +```ts +try { + // ... +} catch (e) { + // ... +} +``` + +## Options + +The rule accepts an options object with the following properties: + +```ts +type Options = { + // if false, disallow specifying : any as the error type as well. See also `no-explicit-any` + allowExplicitAny: boolean; +}; + +const defaults = { + allowExplicitAny: true, +}; +``` + +## Further Reading + +- The original issue report for allowing `: unknown` in error clauses: https://github.com/microsoft/TypeScript/issues/36775 diff --git a/packages/eslint-plugin/src/configs/all.ts b/packages/eslint-plugin/src/configs/all.ts index 642d6f736d07..7775d6698914 100644 --- a/packages/eslint-plugin/src/configs/all.ts +++ b/packages/eslint-plugin/src/configs/all.ts @@ -54,6 +54,7 @@ export = { '@typescript-eslint/no-extraneous-class': 'error', '@typescript-eslint/no-floating-promises': 'error', '@typescript-eslint/no-for-in-array': 'error', + '@typescript-eslint/no-implicit-any-catch': 'error', '@typescript-eslint/no-implied-eval': 'error', '@typescript-eslint/no-inferrable-types': 'error', 'no-invalid-this': 'off', diff --git a/packages/eslint-plugin/src/configs/recommended.ts b/packages/eslint-plugin/src/configs/recommended.ts index 8aac1a8a3b01..0861a1e091dd 100644 --- a/packages/eslint-plugin/src/configs/recommended.ts +++ b/packages/eslint-plugin/src/configs/recommended.ts @@ -10,6 +10,7 @@ export = { 'no-empty-function': 'off', '@typescript-eslint/no-empty-function': 'error', '@typescript-eslint/no-empty-interface': 'error', + '@typescript-eslint/no-implicit-any-catch': 'warn', '@typescript-eslint/no-explicit-any': 'warn', '@typescript-eslint/no-extra-non-null-assertion': 'error', 'no-extra-semi': 'off', diff --git a/packages/eslint-plugin/src/rules/index.ts b/packages/eslint-plugin/src/rules/index.ts index 37ad1da48062..5e36da9a51d1 100644 --- a/packages/eslint-plugin/src/rules/index.ts +++ b/packages/eslint-plugin/src/rules/index.ts @@ -29,6 +29,7 @@ import noDynamicDelete from './no-dynamic-delete'; import noEmptyFunction from './no-empty-function'; import noEmptyInterface from './no-empty-interface'; import noExplicitAny from './no-explicit-any'; +import noImplicitAnyCatch from './no-implicit-any-catch'; import noExtraneousClass from './no-extraneous-class'; import noExtraNonNullAssertion from './no-extra-non-null-assertion'; import noExtraParens from './no-extra-parens'; @@ -131,6 +132,7 @@ export default { 'no-empty-function': noEmptyFunction, 'no-empty-interface': noEmptyInterface, 'no-explicit-any': noExplicitAny, + 'no-implicit-any-catch': noImplicitAnyCatch, 'no-extra-non-null-assertion': noExtraNonNullAssertion, 'no-extra-parens': noExtraParens, 'no-extra-semi': noExtraSemi, diff --git a/packages/eslint-plugin/src/rules/no-implicit-any-catch.ts b/packages/eslint-plugin/src/rules/no-implicit-any-catch.ts new file mode 100644 index 000000000000..81dd2f8cf6f2 --- /dev/null +++ b/packages/eslint-plugin/src/rules/no-implicit-any-catch.ts @@ -0,0 +1,95 @@ +import * as util from '../util'; +import { + TSESLint, + AST_NODE_TYPES, +} from '@typescript-eslint/experimental-utils'; + +export type Options = [ + { + allowExplicitAny: boolean; + }, +]; +export type MessageIds = + | 'implicitAnyInCatch' + | 'explicitAnyInCatch' + | 'suggestExplicitUnknown'; + +export default util.createRule({ + name: 'no-implicit-any-catch', + meta: { + type: 'suggestion', + docs: { + description: 'Disallow usage of the implicit `any` type in catch clauses', + category: 'Best Practices', + recommended: 'warn', + suggestion: true, + }, + fixable: 'code', + messages: { + implicitAnyInCatch: 'Implicit any in catch clause', + explicitAnyInCatch: 'Explicit any in catch clause', + suggestExplicitUnknown: + 'Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct.', + }, + schema: [ + { + type: 'object', + additionalProperties: false, + properties: { + allowExplicitAny: { + type: 'boolean', + }, + }, + }, + ], + }, + defaultOptions: [ + { + allowExplicitAny: true, + }, + ], + create(context, [{ allowExplicitAny }]) { + return { + CatchClause(node): void { + if (!node.param) { + return; // ignore catch without variable + } + + if (!node.param.typeAnnotation) { + context.report({ + node, + messageId: 'implicitAnyInCatch', + suggest: [ + { + messageId: 'suggestExplicitUnknown', + fix(fixer): TSESLint.RuleFix { + return fixer.insertTextAfter(node.param!, ': unknown'); + }, + }, + ], + }); + } else if ( + !allowExplicitAny && + node.param.typeAnnotation.typeAnnotation.type === + AST_NODE_TYPES.TSAnyKeyword + ) { + context.report({ + node, + messageId: 'explicitAnyInCatch', + suggest: [ + { + messageId: 'suggestExplicitUnknown', + fix(fixer): TSESLint.RuleFix { + return fixer.replaceText( + node.param!.typeAnnotation!, + ': unknown', + ); + }, + }, + ], + }); + } + }, + }; + }, +}); diff --git a/packages/eslint-plugin/tests/rules/no-implicit-any-catch.test.ts b/packages/eslint-plugin/tests/rules/no-implicit-any-catch.test.ts new file mode 100644 index 000000000000..7d7dcd95998c --- /dev/null +++ b/packages/eslint-plugin/tests/rules/no-implicit-any-catch.test.ts @@ -0,0 +1,73 @@ +import rule from '../../src/rules/no-implicit-any-catch'; +import { RuleTester } from '../RuleTester'; + +//type InvalidTestCase = TSESLint.InvalidTestCase; +//type SuggestionOutput = TSESLint.SuggestionOutput; + +const ruleTester = new RuleTester({ + parser: '@typescript-eslint/parser', +}); + +ruleTester.run('no-implicit-any-catch', rule, { + valid: [ + ` +try { +} catch (e1: unknown) {} + `, + ` +try { +} catch (e2: any) {} + `, + ], + invalid: [ + { + code: ` +try { +} catch (e3) {} + `.trim(), + errors: [ + { + line: 2, + column: 3, + messageId: 'implicitAnyInCatch', + endLine: 2, + endColumn: 16, + suggestions: [ + { + messageId: 'suggestExplicitUnknown', + output: ` +try { +} catch (e3: unknown) {} + `.trim(), + }, + ], + }, + ], + }, + { + code: ` +try { +} catch (e4: any) {} + `.trim(), + options: [{ allowExplicitAny: false }], + errors: [ + { + line: 2, + column: 3, + messageId: 'explicitAnyInCatch', + endLine: 2, + endColumn: 21, + suggestions: [ + { + messageId: 'suggestExplicitUnknown', + output: ` +try { +} catch (e4: unknown) {} + `.trim(), + }, + ], + }, + ], + }, + ], +}); diff --git a/packages/typescript-estree/src/ast-converter.ts b/packages/typescript-estree/src/ast-converter.ts index ad3b06dbb513..36ca1830ccd7 100644 --- a/packages/typescript-estree/src/ast-converter.ts +++ b/packages/typescript-estree/src/ast-converter.ts @@ -40,10 +40,10 @@ export function astConverter( simpleTraverse(estree, { enter: node => { if (!extra.range) { - delete (node as any).range; + delete node.range; } if (!extra.loc) { - delete (node as any).loc; + delete node.loc; } }, }); From a19c24516b57543fc477bde43d3924fa12c48e78 Mon Sep 17 00:00:00 2001 From: phiresky Date: Thu, 11 Jun 2020 11:54:23 +0200 Subject: [PATCH 03/15] fix(eslint-plugin): [no-implicit-any-catch] disable recommended for now --- packages/eslint-plugin/src/configs/recommended.ts | 2 +- packages/eslint-plugin/src/rules/no-implicit-any-catch.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/eslint-plugin/src/configs/recommended.ts b/packages/eslint-plugin/src/configs/recommended.ts index 0861a1e091dd..cc96cf325899 100644 --- a/packages/eslint-plugin/src/configs/recommended.ts +++ b/packages/eslint-plugin/src/configs/recommended.ts @@ -10,7 +10,7 @@ export = { 'no-empty-function': 'off', '@typescript-eslint/no-empty-function': 'error', '@typescript-eslint/no-empty-interface': 'error', - '@typescript-eslint/no-implicit-any-catch': 'warn', + '@typescript-eslint/no-implicit-any-catch': 'off', '@typescript-eslint/no-explicit-any': 'warn', '@typescript-eslint/no-extra-non-null-assertion': 'error', 'no-extra-semi': 'off', diff --git a/packages/eslint-plugin/src/rules/no-implicit-any-catch.ts b/packages/eslint-plugin/src/rules/no-implicit-any-catch.ts index 81dd2f8cf6f2..820c4f2d2b6a 100644 --- a/packages/eslint-plugin/src/rules/no-implicit-any-catch.ts +++ b/packages/eslint-plugin/src/rules/no-implicit-any-catch.ts @@ -21,7 +21,7 @@ export default util.createRule({ docs: { description: 'Disallow usage of the implicit `any` type in catch clauses', category: 'Best Practices', - recommended: 'warn', + recommended: false, suggestion: true, }, fixable: 'code', From 076e8efded57f9ce6fd45258e2309e0ccc436bac Mon Sep 17 00:00:00 2001 From: phiresky Date: Thu, 11 Jun 2020 11:55:05 +0200 Subject: [PATCH 04/15] fix(typescript-estree): add tests for catch clause type syntax --- .../fixtures/typescript/basics/catch-type-any.src.ts | 5 +++++ .../fixtures/typescript/basics/catch-type-unknown.src.ts | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 packages/shared-fixtures/fixtures/typescript/basics/catch-type-any.src.ts create mode 100644 packages/shared-fixtures/fixtures/typescript/basics/catch-type-unknown.src.ts diff --git a/packages/shared-fixtures/fixtures/typescript/basics/catch-type-any.src.ts b/packages/shared-fixtures/fixtures/typescript/basics/catch-type-any.src.ts new file mode 100644 index 000000000000..4e88b038c941 --- /dev/null +++ b/packages/shared-fixtures/fixtures/typescript/basics/catch-type-any.src.ts @@ -0,0 +1,5 @@ +try { + +} catch (e: any) { + +} diff --git a/packages/shared-fixtures/fixtures/typescript/basics/catch-type-unknown.src.ts b/packages/shared-fixtures/fixtures/typescript/basics/catch-type-unknown.src.ts new file mode 100644 index 000000000000..143574aaf9a4 --- /dev/null +++ b/packages/shared-fixtures/fixtures/typescript/basics/catch-type-unknown.src.ts @@ -0,0 +1,5 @@ +try { + +} catch (e: unknown) { + +} From 4fbde9b8875697fca42345026650798a0a8e40e7 Mon Sep 17 00:00:00 2001 From: phiresky Date: Tue, 16 Jun 2020 16:20:58 +0200 Subject: [PATCH 05/15] Update packages/eslint-plugin/docs/rules/no-implicit-any-catch.md Co-authored-by: Glen --- packages/eslint-plugin/docs/rules/no-implicit-any-catch.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/docs/rules/no-implicit-any-catch.md b/packages/eslint-plugin/docs/rules/no-implicit-any-catch.md index 11503556d17d..1cbfdabca781 100644 --- a/packages/eslint-plugin/docs/rules/no-implicit-any-catch.md +++ b/packages/eslint-plugin/docs/rules/no-implicit-any-catch.md @@ -7,7 +7,7 @@ The noImplicitAny flag in TypeScript does not cover this due to backwards compat ## Rule Details -This rule doesn't requires an explicit type to be declared in the catch clause error argument. +This rule requires an explicit type to be declared in the catch clause error argument. The following pattern is considered a warning: From 4ba7d61509dd8fd32969bcd9851b6d9787030d14 Mon Sep 17 00:00:00 2001 From: phiresky Date: Mon, 22 Jun 2020 10:32:56 +0200 Subject: [PATCH 06/15] fix(typescript-estree): ignore catch clause type fixture from babel --- .../tests/ast-alignment/fixtures-to-test.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/typescript-estree/tests/ast-alignment/fixtures-to-test.ts b/packages/typescript-estree/tests/ast-alignment/fixtures-to-test.ts index eb247042a8f2..a5fc443830ca 100644 --- a/packages/typescript-estree/tests/ast-alignment/fixtures-to-test.ts +++ b/packages/typescript-estree/tests/ast-alignment/fixtures-to-test.ts @@ -418,6 +418,11 @@ tester.addFixturePatternConfig('typescript/basics', { * babel uses a representation that does not match the ESTree spec: https://github.com/estree/estree/pull/205 */ 'export-star-as-ns-from', + /** + * error catch types (TS 4.0), not yet supported in babel as of 2020-06-22 + */ + 'catch-type-any', + 'catch-type-unknown', ], ignoreSourceType: [ /** From cb5be10d16f23df73e080e9aa7aee4f671275b93 Mon Sep 17 00:00:00 2001 From: phiresky Date: Mon, 22 Jun 2020 10:34:41 +0200 Subject: [PATCH 07/15] fix(typescript-estree): add updated snapshots for catch clause type --- .../semantic-diagnostics-enabled.ts.snap | 4 + .../lib/__snapshots__/typescript.ts.snap | 692 ++++++++++++++++++ 2 files changed, 696 insertions(+) diff --git a/packages/typescript-estree/tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap b/packages/typescript-estree/tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap index f94806437fe5..eb5dc2d6bf71 100644 --- a/packages/typescript-estree/tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap +++ b/packages/typescript-estree/tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap @@ -1736,6 +1736,10 @@ exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" e exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/cast-as-simple.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/catch-type-any.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; + +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/catch-type-unknown.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; + exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/class-multi-line-keyword-abstract.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/class-multi-line-keyword-declare.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; diff --git a/packages/typescript-estree/tests/lib/__snapshots__/typescript.ts.snap b/packages/typescript-estree/tests/lib/__snapshots__/typescript.ts.snap index 7a554e8aa898..9930706bf657 100644 --- a/packages/typescript-estree/tests/lib/__snapshots__/typescript.ts.snap +++ b/packages/typescript-estree/tests/lib/__snapshots__/typescript.ts.snap @@ -10899,6 +10899,698 @@ Object { } `; +exports[`typescript fixtures/basics/catch-type-any.src 1`] = ` +Object { + "body": Array [ + Object { + "block": Object { + "body": Array [], + "loc": Object { + "end": Object { + "column": 1, + "line": 3, + }, + "start": Object { + "column": 4, + "line": 1, + }, + }, + "range": Array [ + 4, + 8, + ], + "type": "BlockStatement", + }, + "finalizer": null, + "handler": Object { + "body": Object { + "body": Array [], + "loc": Object { + "end": Object { + "column": 1, + "line": 5, + }, + "start": Object { + "column": 17, + "line": 3, + }, + }, + "range": Array [ + 24, + 28, + ], + "type": "BlockStatement", + }, + "loc": Object { + "end": Object { + "column": 1, + "line": 5, + }, + "start": Object { + "column": 2, + "line": 3, + }, + }, + "param": Object { + "loc": Object { + "end": Object { + "column": 15, + "line": 3, + }, + "start": Object { + "column": 9, + "line": 3, + }, + }, + "name": "e", + "range": Array [ + 16, + 22, + ], + "type": "Identifier", + "typeAnnotation": Object { + "loc": Object { + "end": Object { + "column": 15, + "line": 3, + }, + "start": Object { + "column": 10, + "line": 3, + }, + }, + "range": Array [ + 17, + 22, + ], + "type": "TSTypeAnnotation", + "typeAnnotation": Object { + "loc": Object { + "end": Object { + "column": 15, + "line": 3, + }, + "start": Object { + "column": 12, + "line": 3, + }, + }, + "range": Array [ + 19, + 22, + ], + "type": "TSAnyKeyword", + }, + }, + }, + "range": Array [ + 9, + 28, + ], + "type": "CatchClause", + }, + "loc": Object { + "end": Object { + "column": 1, + "line": 5, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 28, + ], + "type": "TryStatement", + }, + ], + "loc": Object { + "end": Object { + "column": 0, + "line": 6, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 29, + ], + "sourceType": "script", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 3, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 3, + ], + "type": "Keyword", + "value": "try", + }, + Object { + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 4, + "line": 1, + }, + }, + "range": Array [ + 4, + 5, + ], + "type": "Punctuator", + "value": "{", + }, + Object { + "loc": Object { + "end": Object { + "column": 1, + "line": 3, + }, + "start": Object { + "column": 0, + "line": 3, + }, + }, + "range": Array [ + 7, + 8, + ], + "type": "Punctuator", + "value": "}", + }, + Object { + "loc": Object { + "end": Object { + "column": 7, + "line": 3, + }, + "start": Object { + "column": 2, + "line": 3, + }, + }, + "range": Array [ + 9, + 14, + ], + "type": "Keyword", + "value": "catch", + }, + Object { + "loc": Object { + "end": Object { + "column": 9, + "line": 3, + }, + "start": Object { + "column": 8, + "line": 3, + }, + }, + "range": Array [ + 15, + 16, + ], + "type": "Punctuator", + "value": "(", + }, + Object { + "loc": Object { + "end": Object { + "column": 10, + "line": 3, + }, + "start": Object { + "column": 9, + "line": 3, + }, + }, + "range": Array [ + 16, + 17, + ], + "type": "Identifier", + "value": "e", + }, + Object { + "loc": Object { + "end": Object { + "column": 11, + "line": 3, + }, + "start": Object { + "column": 10, + "line": 3, + }, + }, + "range": Array [ + 17, + 18, + ], + "type": "Punctuator", + "value": ":", + }, + Object { + "loc": Object { + "end": Object { + "column": 15, + "line": 3, + }, + "start": Object { + "column": 12, + "line": 3, + }, + }, + "range": Array [ + 19, + 22, + ], + "type": "Identifier", + "value": "any", + }, + Object { + "loc": Object { + "end": Object { + "column": 16, + "line": 3, + }, + "start": Object { + "column": 15, + "line": 3, + }, + }, + "range": Array [ + 22, + 23, + ], + "type": "Punctuator", + "value": ")", + }, + Object { + "loc": Object { + "end": Object { + "column": 18, + "line": 3, + }, + "start": Object { + "column": 17, + "line": 3, + }, + }, + "range": Array [ + 24, + 25, + ], + "type": "Punctuator", + "value": "{", + }, + Object { + "loc": Object { + "end": Object { + "column": 1, + "line": 5, + }, + "start": Object { + "column": 0, + "line": 5, + }, + }, + "range": Array [ + 27, + 28, + ], + "type": "Punctuator", + "value": "}", + }, + ], + "type": "Program", +} +`; + +exports[`typescript fixtures/basics/catch-type-unknown.src 1`] = ` +Object { + "body": Array [ + Object { + "block": Object { + "body": Array [], + "loc": Object { + "end": Object { + "column": 1, + "line": 3, + }, + "start": Object { + "column": 4, + "line": 1, + }, + }, + "range": Array [ + 4, + 8, + ], + "type": "BlockStatement", + }, + "finalizer": null, + "handler": Object { + "body": Object { + "body": Array [], + "loc": Object { + "end": Object { + "column": 1, + "line": 5, + }, + "start": Object { + "column": 21, + "line": 3, + }, + }, + "range": Array [ + 28, + 32, + ], + "type": "BlockStatement", + }, + "loc": Object { + "end": Object { + "column": 1, + "line": 5, + }, + "start": Object { + "column": 2, + "line": 3, + }, + }, + "param": Object { + "loc": Object { + "end": Object { + "column": 19, + "line": 3, + }, + "start": Object { + "column": 9, + "line": 3, + }, + }, + "name": "e", + "range": Array [ + 16, + 26, + ], + "type": "Identifier", + "typeAnnotation": Object { + "loc": Object { + "end": Object { + "column": 19, + "line": 3, + }, + "start": Object { + "column": 10, + "line": 3, + }, + }, + "range": Array [ + 17, + 26, + ], + "type": "TSTypeAnnotation", + "typeAnnotation": Object { + "loc": Object { + "end": Object { + "column": 19, + "line": 3, + }, + "start": Object { + "column": 12, + "line": 3, + }, + }, + "range": Array [ + 19, + 26, + ], + "type": "TSUnknownKeyword", + }, + }, + }, + "range": Array [ + 9, + 32, + ], + "type": "CatchClause", + }, + "loc": Object { + "end": Object { + "column": 1, + "line": 5, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 32, + ], + "type": "TryStatement", + }, + ], + "loc": Object { + "end": Object { + "column": 0, + "line": 6, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 33, + ], + "sourceType": "script", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 3, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 3, + ], + "type": "Keyword", + "value": "try", + }, + Object { + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 4, + "line": 1, + }, + }, + "range": Array [ + 4, + 5, + ], + "type": "Punctuator", + "value": "{", + }, + Object { + "loc": Object { + "end": Object { + "column": 1, + "line": 3, + }, + "start": Object { + "column": 0, + "line": 3, + }, + }, + "range": Array [ + 7, + 8, + ], + "type": "Punctuator", + "value": "}", + }, + Object { + "loc": Object { + "end": Object { + "column": 7, + "line": 3, + }, + "start": Object { + "column": 2, + "line": 3, + }, + }, + "range": Array [ + 9, + 14, + ], + "type": "Keyword", + "value": "catch", + }, + Object { + "loc": Object { + "end": Object { + "column": 9, + "line": 3, + }, + "start": Object { + "column": 8, + "line": 3, + }, + }, + "range": Array [ + 15, + 16, + ], + "type": "Punctuator", + "value": "(", + }, + Object { + "loc": Object { + "end": Object { + "column": 10, + "line": 3, + }, + "start": Object { + "column": 9, + "line": 3, + }, + }, + "range": Array [ + 16, + 17, + ], + "type": "Identifier", + "value": "e", + }, + Object { + "loc": Object { + "end": Object { + "column": 11, + "line": 3, + }, + "start": Object { + "column": 10, + "line": 3, + }, + }, + "range": Array [ + 17, + 18, + ], + "type": "Punctuator", + "value": ":", + }, + Object { + "loc": Object { + "end": Object { + "column": 19, + "line": 3, + }, + "start": Object { + "column": 12, + "line": 3, + }, + }, + "range": Array [ + 19, + 26, + ], + "type": "Identifier", + "value": "unknown", + }, + Object { + "loc": Object { + "end": Object { + "column": 20, + "line": 3, + }, + "start": Object { + "column": 19, + "line": 3, + }, + }, + "range": Array [ + 26, + 27, + ], + "type": "Punctuator", + "value": ")", + }, + Object { + "loc": Object { + "end": Object { + "column": 22, + "line": 3, + }, + "start": Object { + "column": 21, + "line": 3, + }, + }, + "range": Array [ + 28, + 29, + ], + "type": "Punctuator", + "value": "{", + }, + Object { + "loc": Object { + "end": Object { + "column": 1, + "line": 5, + }, + "start": Object { + "column": 0, + "line": 5, + }, + }, + "range": Array [ + 31, + 32, + ], + "type": "Punctuator", + "value": "}", + }, + ], + "type": "Program", +} +`; + exports[`typescript fixtures/basics/class-multi-line-keyword-abstract.src 1`] = ` Object { "body": Array [ From 75533af79fe913f2a7686a65affa663d263c24ec Mon Sep 17 00:00:00 2001 From: phiresky Date: Fri, 3 Jul 2020 18:23:27 +0200 Subject: [PATCH 08/15] fix(typescript-estree): no-implicit-any-cache: add commented out types to doc to work around prettier force formatting --- packages/eslint-plugin/docs/rules/no-implicit-any-catch.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/no-implicit-any-catch.md b/packages/eslint-plugin/docs/rules/no-implicit-any-catch.md index 1cbfdabca781..eff5461eb13d 100644 --- a/packages/eslint-plugin/docs/rules/no-implicit-any-catch.md +++ b/packages/eslint-plugin/docs/rules/no-implicit-any-catch.md @@ -24,7 +24,7 @@ The following patterns are not warnings: ```ts try { // ... -} catch (e) { +} catch (e /*: unknown*/) { // ... } ``` @@ -32,7 +32,7 @@ try { ```ts try { // ... -} catch (e) { +} catch (e /*: any*/) { // ... } ``` From 3aa4c07bd7920b30847ea7260e822438c482d9d6 Mon Sep 17 00:00:00 2001 From: phiresky Date: Fri, 3 Jul 2020 18:24:24 +0200 Subject: [PATCH 09/15] chore: upgrade typescript for catch clause type --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index e01a0ed0c896..7ec5dea4ca2c 100644 --- a/package.json +++ b/package.json @@ -95,6 +95,6 @@ "typescript": ">=3.3.1 <4.0.0" }, "resolutions": { - "typescript": "3.9.2" + "typescript": "4.0.0-dev.20200703" } } diff --git a/yarn.lock b/yarn.lock index 337037083ad9..8b1edf878625 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8535,10 +8535,10 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript@*, typescript@3.9.2, "typescript@>=3.3.1 <4.0.0", typescript@^3.8.0-dev.20200111: - version "3.9.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.2.tgz#64e9c8e9be6ea583c54607677dd4680a1cf35db9" - integrity sha512-q2ktq4n/uLuNNShyayit+DTobV2ApPEo/6so68JaD5ojvc/6GClBipedB9zNWYxRSAlZXAe405Rlijzl6qDiSw== +typescript@*, typescript@4.0.0-dev.20200703, "typescript@>=3.3.1 <4.0.0", typescript@^3.8.0-dev.20200111: + version "4.0.0-dev.20200703" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.0-dev.20200703.tgz#18a169ce8cc29d49f329262c665f03c7c27e8ead" + integrity sha512-xoluPKssy9HuHbbyc6cMB/xv8JPezBjBO0dpyR5O9WEvUYF4QVu+3TtaGcdG/d+NpwgGBqo0cR6IAeHxJuGmXw== uc.micro@^1.0.1, uc.micro@^1.0.5: version "1.0.6" From d89ccd37aa406dab7748a1aa6ab473fbfc42eb7c Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Sun, 12 Jul 2020 23:34:17 -0700 Subject: [PATCH 10/15] update to 4.0.0-beta and fix errors --- package.json | 2 +- .../docs/rules/no-implicit-any-catch.md | 51 +++++++++++++------ .../src/rules/no-implicit-any-catch.ts | 2 +- .../tests/rules/no-implicit-any-catch.test.ts | 15 ++++-- .../typescript-estree/src/ast-converter.ts | 4 ++ packages/typescript-estree/src/convert.ts | 12 +++-- packages/typescript-estree/src/node-utils.ts | 3 ++ yarn.lock | 8 +-- 8 files changed, 66 insertions(+), 31 deletions(-) diff --git a/package.json b/package.json index cb64f89fb2c3..5f969ca494a9 100644 --- a/package.json +++ b/package.json @@ -96,6 +96,6 @@ "typescript": ">=3.3.1 <4.0.0" }, "resolutions": { - "typescript": "4.0.0-dev.20200703" + "typescript": "4.0.0-beta" } } diff --git a/packages/eslint-plugin/docs/rules/no-implicit-any-catch.md b/packages/eslint-plugin/docs/rules/no-implicit-any-catch.md index eff5461eb13d..8ef946b42865 100644 --- a/packages/eslint-plugin/docs/rules/no-implicit-any-catch.md +++ b/packages/eslint-plugin/docs/rules/no-implicit-any-catch.md @@ -1,13 +1,14 @@ # Disallow usage of the implicit `any` type in catch clauses (`no-implicit-any-catch`) -Using the `any` type defeats the purpose of using TypeScript. -When `any` is used, all compiler type checks around that value are ignored. +TypeScript 4.0 added support for adding an explicit `any` or `unknown` type annotation on a catch clause variable. -The noImplicitAny flag in TypeScript does not cover this due to backwards compatibility reasons. +By default, TypeScript will type a catch clause variable as `any`, so explicitly annotating it as `unknown` can add a lot of safety to your codebase. + +The `noImplicitAny` flag in TypeScript does not cover this for backwards compatibility reasons. ## Rule Details -This rule requires an explicit type to be declared in the catch clause error argument. +This rule requires an explicit type to be declared on a catch clause variable. The following pattern is considered a warning: @@ -19,39 +20,57 @@ try { } ``` -The following patterns are not warnings: +The following pattern is **_not_** considered a warning: -```ts -try { - // ... -} catch (e /*: unknown*/) { - // ... -} -``` + + ```ts try { // ... -} catch (e /*: any*/) { +} catch (e: unknown) { // ... } ``` + + ## Options The rule accepts an options object with the following properties: ```ts type Options = { - // if false, disallow specifying : any as the error type as well. See also `no-explicit-any` + // if false, disallow specifying `: any` as the error type as well. See also `no-explicit-any` allowExplicitAny: boolean; }; const defaults = { - allowExplicitAny: true, + allowExplicitAny: false, }; ``` +### `allowExplicitAny` + +The follow is is **_not_** considered a warning with `{ allowExplicitAny: true }` + + + + +```ts +try { + // ... +} catch (e: any) { + // ... +} +``` + + + +## When Not To Use It + +If you are not using TypeScript 4.0 (or greater), then you will not be able to use this rule, annotations on catch clauses is not supported. + ## Further Reading -- The original issue report for allowing `: unknown` in error clauses: https://github.com/microsoft/TypeScript/issues/36775 +- [TypeScript 4.0 Beta Release Notes](https://devblogs.microsoft.com/typescript/announcing-typescript-4-0-beta/#unknown-on-catch) diff --git a/packages/eslint-plugin/src/rules/no-implicit-any-catch.ts b/packages/eslint-plugin/src/rules/no-implicit-any-catch.ts index 820c4f2d2b6a..aed526f8ab01 100644 --- a/packages/eslint-plugin/src/rules/no-implicit-any-catch.ts +++ b/packages/eslint-plugin/src/rules/no-implicit-any-catch.ts @@ -45,7 +45,7 @@ export default util.createRule({ }, defaultOptions: [ { - allowExplicitAny: true, + allowExplicitAny: false, }, ], create(context, [{ allowExplicitAny }]) { diff --git a/packages/eslint-plugin/tests/rules/no-implicit-any-catch.test.ts b/packages/eslint-plugin/tests/rules/no-implicit-any-catch.test.ts index 7d7dcd95998c..f8113555086e 100644 --- a/packages/eslint-plugin/tests/rules/no-implicit-any-catch.test.ts +++ b/packages/eslint-plugin/tests/rules/no-implicit-any-catch.test.ts @@ -1,9 +1,11 @@ +/* eslint-disable eslint-comments/no-use */ +// TODO - prettier currently removes the type annotations, re-enable this once prettier is updated +/* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ +/* eslint-enable eslint-comments/no-use */ + import rule from '../../src/rules/no-implicit-any-catch'; import { RuleTester } from '../RuleTester'; -//type InvalidTestCase = TSESLint.InvalidTestCase; -//type SuggestionOutput = TSESLint.SuggestionOutput; - const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', }); @@ -14,10 +16,13 @@ ruleTester.run('no-implicit-any-catch', rule, { try { } catch (e1: unknown) {} `, - ` + { + code: ` try { } catch (e2: any) {} - `, + `, + options: [{ allowExplicitAny: true }], + }, ], invalid: [ { diff --git a/packages/typescript-estree/src/ast-converter.ts b/packages/typescript-estree/src/ast-converter.ts index 36ca1830ccd7..e42f722ff66d 100644 --- a/packages/typescript-estree/src/ast-converter.ts +++ b/packages/typescript-estree/src/ast-converter.ts @@ -40,9 +40,13 @@ export function astConverter( simpleTraverse(estree, { enter: node => { if (!extra.range) { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TS 4.0 made this an error because the types aren't optional + // @ts-expect-error delete node.range; } if (!extra.loc) { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TS 4.0 made this an error because the types aren't optional + // @ts-expect-error delete node.loc; } }, diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index eac3f65a8e17..d77b4b8ddaa6 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -1989,7 +1989,7 @@ export class Converter { type: AST_NODE_TYPES.TSNullKeyword, }); } else { - return this.createNode(node as ts.NullLiteral, { + return this.createNode(node, { type: AST_NODE_TYPES.Literal, value: null, raw: 'null', @@ -2620,9 +2620,13 @@ export class Converter { // In TS 4.0, the `elementTypes` property was changed to `elements`. // To support both at compile time, we cast to access the newer version // if the former does not exist. - const elementTypes = node.elementTypes - ? node.elementTypes.map(el => this.convertType(el)) - : (node as any).elements.map((el: ts.Node) => this.convertType(el)); + type Elements = typeof node.elements; + const elementTypes = + 'elementTypes' in node + ? ((node as any).elementTypes as Elements).map(el => + this.convertType(el), + ) + : node.elements.map(el => this.convertType(el)); return this.createNode(node, { type: AST_NODE_TYPES.TSTupleType, diff --git a/packages/typescript-estree/src/node-utils.ts b/packages/typescript-estree/src/node-utils.ts index 39459935c87c..b97f78b8dbdd 100644 --- a/packages/typescript-estree/src/node-utils.ts +++ b/packages/typescript-estree/src/node-utils.ts @@ -67,8 +67,11 @@ interface TokenToText { [SyntaxKind.GreaterThanGreaterThanEqualsToken]: '>>='; [SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken]: '>>>='; [SyntaxKind.AmpersandEqualsToken]: '&='; + [SyntaxKind.AmpersandAmpersandEqualsToken]: '&&='; [SyntaxKind.BarEqualsToken]: '|='; + [SyntaxKind.BarBarEqualsToken]: '||='; [SyntaxKind.CaretEqualsToken]: '^='; + [SyntaxKind.QuestionQuestionEqualsToken]: '??='; [SyntaxKind.AtToken]: '@'; [SyntaxKind.InKeyword]: 'in'; [SyntaxKind.UniqueKeyword]: 'unique'; diff --git a/yarn.lock b/yarn.lock index 760793b7b7b6..7f1354f35ad3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8577,10 +8577,10 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript@*, typescript@4.0.0-dev.20200703, "typescript@>=3.3.1 <4.0.0", typescript@^3.8.0-dev.20200111: - version "4.0.0-dev.20200703" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.0-dev.20200703.tgz#18a169ce8cc29d49f329262c665f03c7c27e8ead" - integrity sha512-xoluPKssy9HuHbbyc6cMB/xv8JPezBjBO0dpyR5O9WEvUYF4QVu+3TtaGcdG/d+NpwgGBqo0cR6IAeHxJuGmXw== +typescript@*, typescript@4.0.0-beta, "typescript@>=3.3.1 <4.0.0", typescript@^3.8.0-dev.20200111: + version "4.0.0-beta" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.0-beta.tgz#a6a65e430562131de69496a3ef5484346bc0cdd2" + integrity sha512-d3s/CogGtB2uPZ2Z8ts6eoUxxyB9PH3R27/UrzvpthuOvpCg4FWWnBbBiqJ0K4eu6eTlgmLiqQkh2dquReJweA== uc.micro@^1.0.1, uc.micro@^1.0.5: version "1.0.6" From 22282b1a38eb7243cb6b5a56c9ce08019c7181ab Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 13 Jul 2020 09:25:19 -0700 Subject: [PATCH 11/15] fix yarn lockfile not freezing --- package.json | 2 +- yarn.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 5f969ca494a9..f933527967f6 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,7 @@ "ts-jest": "^25.5.1", "ts-node": "^8.10.1", "tslint": "^6.1.2", - "typescript": ">=3.3.1 <4.0.0" + "typescript": ">=3.3.1 <4.0.0 || 4.0.0-beta" }, "resolutions": { "typescript": "4.0.0-beta" diff --git a/yarn.lock b/yarn.lock index 7f1354f35ad3..55dd38c29bfb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8577,7 +8577,7 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript@*, typescript@4.0.0-beta, "typescript@>=3.3.1 <4.0.0", typescript@^3.8.0-dev.20200111: +typescript@*, typescript@4.0.0-beta, "typescript@>=3.3.1 <4.0.0 || 4.0.0-beta", typescript@^3.8.0-dev.20200111: version "4.0.0-beta" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.0-beta.tgz#a6a65e430562131de69496a3ef5484346bc0cdd2" integrity sha512-d3s/CogGtB2uPZ2Z8ts6eoUxxyB9PH3R27/UrzvpthuOvpCg4FWWnBbBiqJ0K4eu6eTlgmLiqQkh2dquReJweA== From 61dcd4e77bc2c434e5182cda15843f168f765c4f Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 13 Jul 2020 09:37:58 -0700 Subject: [PATCH 12/15] fix type error --- packages/typescript-estree/tests/lib/convert.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/typescript-estree/tests/lib/convert.ts b/packages/typescript-estree/tests/lib/convert.ts index 0dd26908dd6d..52bd377a5bfe 100644 --- a/packages/typescript-estree/tests/lib/convert.ts +++ b/packages/typescript-estree/tests/lib/convert.ts @@ -19,6 +19,8 @@ describe('convert', () => { function fakeUnknownKind(node: ts.Node): void { ts.forEachChild(node, fakeUnknownKind); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- intentionally writing to a readonly field + // @ts-expect-error node.kind = ts.SyntaxKind.UnparsedPrologue; } From acc2bde08b894e711fe2a0259a449f1c71891067 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 13 Jul 2020 09:59:42 -0700 Subject: [PATCH 13/15] update snaps --- .../tests/lib/__snapshots__/convert.ts.snap | 24 +++- .../semantic-diagnostics-enabled.ts.snap | 8 +- .../lib/__snapshots__/typescript.ts.snap | 107 ++++++++++++++++-- 3 files changed, 119 insertions(+), 20 deletions(-) diff --git a/packages/typescript-estree/tests/lib/__snapshots__/convert.ts.snap b/packages/typescript-estree/tests/lib/__snapshots__/convert.ts.snap index 448b85afda1f..7da28080eb36 100644 --- a/packages/typescript-estree/tests/lib/__snapshots__/convert.ts.snap +++ b/packages/typescript-estree/tests/lib/__snapshots__/convert.ts.snap @@ -170,7 +170,7 @@ Object { }, ], "text": "new foo()", - "transformFlags": 0, + "transformFlags": 9, "type": "TSSourceFile", "typeReferenceDirectives": Array [], } @@ -190,6 +190,8 @@ Object { "line": 1, }, }, + "localSymbol": undefined, + "locals": undefined, "modifiers": undefined, "name": Object { "escapedText": "foo", @@ -203,6 +205,7 @@ Object { "line": 1, }, }, + "originalKeywordKind": undefined, "range": Array [ 5, 8, @@ -210,11 +213,13 @@ Object { "transformFlags": 0, "type": "TSUnparsedPrologue", }, + "nextContainer": undefined, "range": Array [ 0, 35, ], - "transformFlags": 0, + "symbol": undefined, + "transformFlags": 1, "type": "TSUnparsedPrologue", "typeAnnotation": null, "typeParameters": null, @@ -289,6 +294,8 @@ Object { "line": 1, }, }, + "localSymbol": undefined, + "locals": undefined, "members": Array [], "modifiers": undefined, "name": Object { @@ -309,11 +316,13 @@ Object { ], "type": "Identifier", }, + "nextContainer": undefined, "range": Array [ 0, 18, ], - "transformFlags": 0, + "symbol": undefined, + "transformFlags": 2305, "type": "TSClassDeclaration", "typeParameters": null, } @@ -354,7 +363,7 @@ Object { 0, 12, ], - "transformFlags": 0, + "transformFlags": 9, "type": "TSNewExpression", "typeParameters": Object { "loc": Object { @@ -427,7 +436,10 @@ Object { "line": 1, }, }, + "localSymbol": undefined, + "locals": undefined, "members": Array [], + "modifiers": undefined, "name": Object { "loc": Object { "end": Object { @@ -446,11 +458,13 @@ Object { ], "type": "Identifier", }, + "nextContainer": undefined, "range": Array [ 0, 15, ], - "transformFlags": 0, + "symbol": undefined, + "transformFlags": 257, "type": "TSClassDeclaration", "typeParameters": Object { "loc": Object { diff --git a/packages/typescript-estree/tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap b/packages/typescript-estree/tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap index eb5dc2d6bf71..77b52a840d02 100644 --- a/packages/typescript-estree/tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap +++ b/packages/typescript-estree/tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap @@ -1499,8 +1499,8 @@ Object { exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/jsx/invalid-no-common-parent.src 1`] = ` Object { - "column": 36, - "index": 36, + "column": 8, + "index": 8, "lineNumber": 1, "message": "JSX expressions must have one parent element.", } @@ -1508,8 +1508,8 @@ Object { exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/jsx/invalid-no-common-parent-with-comment.src 1`] = ` Object { - "column": 63, - "index": 63, + "column": 8, + "index": 8, "lineNumber": 1, "message": "JSX expressions must have one parent element.", } diff --git a/packages/typescript-estree/tests/lib/__snapshots__/typescript.ts.snap b/packages/typescript-estree/tests/lib/__snapshots__/typescript.ts.snap index 9930706bf657..65d208d69c3c 100644 --- a/packages/typescript-estree/tests/lib/__snapshots__/typescript.ts.snap +++ b/packages/typescript-estree/tests/lib/__snapshots__/typescript.ts.snap @@ -81477,6 +81477,23 @@ Object { ], "type": "TSTypeAnnotation", "typeAnnotation": Object { + "literal": Object { + "loc": Object { + "end": Object { + "column": 11, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 11, + ], + "type": "TSNullKeyword", + }, "loc": Object { "end": Object { "column": 11, @@ -81491,7 +81508,7 @@ Object { 7, 11, ], - "type": "TSNullKeyword", + "type": "TSLiteralType", }, }, }, @@ -122691,6 +122708,23 @@ Object { ], "type": "TSTypeAliasDeclaration", "typeAnnotation": Object { + "literal": Object { + "loc": Object { + "end": Object { + "column": 15, + "line": 1, + }, + "start": Object { + "column": 11, + "line": 1, + }, + }, + "range": Array [ + 11, + 15, + ], + "type": "TSNullKeyword", + }, "loc": Object { "end": Object { "column": 15, @@ -122705,7 +122739,7 @@ Object { 11, 15, ], - "type": "TSNullKeyword", + "type": "TSLiteralType", }, }, ], @@ -147111,7 +147145,7 @@ Object { 7, 14, ], - "transformFlags": 0, + "transformFlags": 1, "type": "TSPrivateKeyword", }, Object { @@ -147129,7 +147163,7 @@ Object { 15, 21, ], - "transformFlags": 0, + "transformFlags": 1, "type": "TSPublicKeyword", }, Object { @@ -147147,7 +147181,7 @@ Object { 22, 31, ], - "transformFlags": 0, + "transformFlags": 1, "type": "TSProtectedKeyword", }, Object { @@ -147165,7 +147199,7 @@ Object { 32, 38, ], - "transformFlags": 0, + "transformFlags": 256, "type": "TSStaticKeyword", }, Object { @@ -147183,7 +147217,7 @@ Object { 39, 47, ], - "transformFlags": 0, + "transformFlags": 1, "type": "TSReadonlyKeyword", }, Object { @@ -147218,7 +147252,7 @@ Object { 57, 62, ], - "transformFlags": 0, + "transformFlags": 96, "type": "TSAsyncKeyword", }, ], @@ -165613,6 +165647,23 @@ Object { "type": "TSStringKeyword", }, "falseType": Object { + "literal": Object { + "loc": Object { + "end": Object { + "column": 45, + "line": 1, + }, + "start": Object { + "column": 41, + "line": 1, + }, + }, + "range": Array [ + 41, + 45, + ], + "type": "TSNullKeyword", + }, "loc": Object { "end": Object { "column": 45, @@ -165627,7 +165678,7 @@ Object { 41, 45, ], - "type": "TSNullKeyword", + "type": "TSLiteralType", }, "loc": Object { "end": Object { @@ -176645,6 +176696,23 @@ Object { "type": "TSIntersectionType", "types": Array [ Object { + "literal": Object { + "loc": Object { + "end": Object { + "column": 62, + "line": 1, + }, + "start": Object { + "column": 58, + "line": 1, + }, + }, + "range": Array [ + 58, + 62, + ], + "type": "TSNullKeyword", + }, "loc": Object { "end": Object { "column": 62, @@ -176659,7 +176727,7 @@ Object { 58, 62, ], - "type": "TSNullKeyword", + "type": "TSLiteralType", }, Object { "elementType": Object { @@ -186141,6 +186209,23 @@ Object { "type": "TSNumberKeyword", }, Object { + "literal": Object { + "loc": Object { + "end": Object { + "column": 24, + "line": 1, + }, + "start": Object { + "column": 20, + "line": 1, + }, + }, + "range": Array [ + 20, + 24, + ], + "type": "TSNullKeyword", + }, "loc": Object { "end": Object { "column": 24, @@ -186155,7 +186240,7 @@ Object { 20, 24, ], - "type": "TSNullKeyword", + "type": "TSLiteralType", }, Object { "loc": Object { From eb14de83969653df8efc7ea710b18542be1557c0 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Sat, 18 Jul 2020 18:59:18 -0700 Subject: [PATCH 14/15] fix recommended config --- packages/eslint-plugin/src/configs/recommended.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/eslint-plugin/src/configs/recommended.ts b/packages/eslint-plugin/src/configs/recommended.ts index 14f3e22f1b7b..d9450197c415 100644 --- a/packages/eslint-plugin/src/configs/recommended.ts +++ b/packages/eslint-plugin/src/configs/recommended.ts @@ -14,7 +14,6 @@ export = { 'no-empty-function': 'off', '@typescript-eslint/no-empty-function': 'error', '@typescript-eslint/no-empty-interface': 'error', - '@typescript-eslint/no-implicit-any-catch': 'off', '@typescript-eslint/no-explicit-any': 'warn', '@typescript-eslint/no-extra-non-null-assertion': 'error', 'no-extra-semi': 'off', From 3f724c416e2c3062e789d5dd95220b30a3581cc9 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Sat, 18 Jul 2020 19:28:19 -0700 Subject: [PATCH 15/15] =?UTF-8?q?update=20readme=E2=80=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/eslint-plugin/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/README.md b/packages/eslint-plugin/README.md index 54886a535c02..0b1090d1ac4b 100644 --- a/packages/eslint-plugin/README.md +++ b/packages/eslint-plugin/README.md @@ -122,7 +122,7 @@ Pro Tip: For larger codebases you may want to consider splitting our linting int | [`@typescript-eslint/no-extraneous-class`](./docs/rules/no-extraneous-class.md) | Forbids the use of classes as namespaces | | | | | [`@typescript-eslint/no-floating-promises`](./docs/rules/no-floating-promises.md) | Requires Promise-like values to be handled appropriately | :heavy_check_mark: | | :thought_balloon: | | [`@typescript-eslint/no-for-in-array`](./docs/rules/no-for-in-array.md) | Disallow iterating over an array with a for-in loop | :heavy_check_mark: | | :thought_balloon: | -| [`@typescript-eslint/no-implicit-any-catch`](./docs/rules/no-implicit-any-catch.md) | Disallow usage of the implicit `any` type in catch clauses | :heavy_check_mark: | :wrench: | | +| [`@typescript-eslint/no-implicit-any-catch`](./docs/rules/no-implicit-any-catch.md) | Disallow usage of the implicit `any` type in catch clauses | | :wrench: | | | [`@typescript-eslint/no-implied-eval`](./docs/rules/no-implied-eval.md) | Disallow the use of `eval()`-like methods | :heavy_check_mark: | | :thought_balloon: | | [`@typescript-eslint/no-inferrable-types`](./docs/rules/no-inferrable-types.md) | Disallows explicit type declarations for variables or parameters initialized to a number, string, or boolean | :heavy_check_mark: | :wrench: | | | [`@typescript-eslint/no-invalid-void-type`](./docs/rules/no-invalid-void-type.md) | Disallows usage of `void` type outside of generic or return types | | | |