From af2c00de62f7e31eaeb88996ebf3f330cc8473b9 Mon Sep 17 00:00:00 2001 From: garyking Date: Sun, 12 Apr 2020 01:38:59 -0400 Subject: [PATCH] feat(eslint-plugin): [consistent-type-assertions] always allow `const` assertions (#1713) --- .../docs/rules/consistent-type-assertions.md | 2 ++ .../src/rules/consistent-type-assertions.ts | 20 +++++++++++++++++-- .../rules/consistent-type-assertions.test.ts | 18 +++++++++++++++-- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/consistent-type-assertions.md b/packages/eslint-plugin/docs/rules/consistent-type-assertions.md index cdf0fb7656c..43e67b755b5 100644 --- a/packages/eslint-plugin/docs/rules/consistent-type-assertions.md +++ b/packages/eslint-plugin/docs/rules/consistent-type-assertions.md @@ -8,6 +8,8 @@ Type assertions are also commonly referred as "type casting" in TypeScript (even In addition to ensuring that type assertions are written in a consistent way, this rule also helps make your codebase more type-safe. +`const` assertions, [introduced in TypeScript 3.4](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions), is always allowed by this rule. Examples of it include `let x = "hello" as const;` and `let x = "hello";`. + ## Options ```ts diff --git a/packages/eslint-plugin/src/rules/consistent-type-assertions.ts b/packages/eslint-plugin/src/rules/consistent-type-assertions.ts index ae54149d0a7..0620822f83c 100644 --- a/packages/eslint-plugin/src/rules/consistent-type-assertions.ts +++ b/packages/eslint-plugin/src/rules/consistent-type-assertions.ts @@ -75,10 +75,27 @@ export default util.createRule({ create(context, [options]) { const sourceCode = context.getSourceCode(); + function isConst(node: TSESTree.TypeNode): boolean { + if (node.type !== AST_NODE_TYPES.TSTypeReference) { + return false; + } + + return ( + node.typeName.type === AST_NODE_TYPES.Identifier && + node.typeName.name === 'const' + ); + } + function reportIncorrectAssertionType( node: TSESTree.TSTypeAssertion | TSESTree.TSAsExpression, ): void { + // If this node is `as const`, then don't report an error. + if (isConst(node.typeAnnotation)) { + return; + } + const messageId = options.assertionStyle; + context.report({ node, messageId, @@ -97,8 +114,7 @@ export default util.createRule({ case AST_NODE_TYPES.TSTypeReference: return ( // Ignore `as const` and `` - (node.typeName.type === AST_NODE_TYPES.Identifier && - node.typeName.name !== 'const') || + !isConst(node) || // Allow qualified names which have dots between identifiers, `Foo.Bar` node.typeName.type === AST_NODE_TYPES.TSQualifiedName ); 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 f885d503091..010bb894ad7 100644 --- a/packages/eslint-plugin/tests/rules/consistent-type-assertions.test.ts +++ b/packages/eslint-plugin/tests/rules/consistent-type-assertions.test.ts @@ -9,14 +9,12 @@ const ANGLE_BRACKET_TESTS = ` const x = new Generic(); const x = b; const x = [1]; -const x = [1]; const x = ('string'); `; const AS_TESTS = ` const x = new Generic() as Foo; const x = b as A; const x = [1] as readonly number[]; -const x = [1] as const; const x = ('string') as a | b; `; const OBJECT_LITERAL_AS_CASTS = ` @@ -98,6 +96,22 @@ ruleTester.run('consistent-type-assertions', rule, { }, ], }), + { + code: 'const x = [1];', + options: [ + { + assertionStyle: 'never', + }, + ], + }, + { + code: 'const x = [1] as const;', + options: [ + { + assertionStyle: 'never', + }, + ], + }, ], invalid: [ ...batchedSingleLineTests({