From 9b4de1fa41b854db41f30ba0bf179ed12cca1511 Mon Sep 17 00:00:00 2001 From: mdm317 Date: Fri, 20 Dec 2024 00:57:00 +0900 Subject: [PATCH 1/4] fix : add case when cast type is a template literal or a union type. --- .../rules/no-unnecessary-type-assertion.ts | 17 +++++++++++---- .../no-unnecessary-type-assertion.test.ts | 21 +++++++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts b/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts index c73d8717c3e1..f5caf697197d 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts @@ -13,6 +13,7 @@ import { getDeclaration, getModifiers, getParserServices, + getTypeName, isNullableType, isTypeFlagSet, nullThrows, @@ -223,10 +224,18 @@ export default createRule({ const castType = services.getTypeAtLocation(node); const uncastType = services.getTypeAtLocation(node.expression); const typeIsUnchanged = isTypeUnchanged(uncastType, castType); - - const wouldSameTypeBeInferred = castType.isLiteral() - ? isImplicitlyNarrowedConstDeclaration(node) - : !isConstAssertion(node.typeAnnotation); + const isCastTypeTemplateLiteral = + node.typeAnnotation.type === AST_NODE_TYPES.TSTemplateLiteralType; + + const isCastTypeUnionStringlike = + castType.isUnion() && getTypeName(checker, castType) === 'string'; + + const wouldSameTypeBeInferred = + castType.isLiteral() || + isCastTypeTemplateLiteral || + isCastTypeUnionStringlike + ? isImplicitlyNarrowedConstDeclaration(node) + : !isConstAssertion(node.typeAnnotation); if (typeIsUnchanged && wouldSameTypeBeInferred) { context.report({ diff --git a/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts index db8309164efb..8d4660cf8c17 100644 --- a/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts @@ -358,6 +358,16 @@ if (Math.random()) { x!; `, }, + "let a = (Date.now() % 2 ? 'a' : 'b') as 'a' | 'b';", + noFormat` + const state: "expired" | "pending" = "pending"; + + function main() { + return { + type: \`\${state}Request\` as \`\${typeof state}Request\` + }; + } + `, ], invalid: [ @@ -1151,5 +1161,16 @@ const a = ''; const b: string | undefined = (a ? undefined : a); `, }, + { + code: "const a = (Date.now() % 2 ? 'a' : 'b') as 'a' | 'b';", + errors: [ + { + column: 11, + line: 1, + messageId: 'unnecessaryAssertion', + }, + ], + output: `const a = (Date.now() % 2 ? 'a' : 'b');`, + }, ], }); From 0b88ee2ff1ddf86ef7744ac6d54979a2ec4c9a7f Mon Sep 17 00:00:00 2001 From: mdm317 <62943813+mdm317@users.noreply.github.com> Date: Wed, 1 Jan 2025 14:33:20 +0900 Subject: [PATCH 2/4] avoid using cast the word cast --- .../src/rules/no-unnecessary-type-assertion.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts b/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts index f5caf697197d..1ea069180ae4 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts @@ -224,16 +224,16 @@ export default createRule({ const castType = services.getTypeAtLocation(node); const uncastType = services.getTypeAtLocation(node.expression); const typeIsUnchanged = isTypeUnchanged(uncastType, castType); - const isCastTypeTemplateLiteral = + const isAssertionTypeTemplateLiteral = node.typeAnnotation.type === AST_NODE_TYPES.TSTemplateLiteralType; - const isCastTypeUnionStringlike = + const isAssertionTypeUnionStringlike = castType.isUnion() && getTypeName(checker, castType) === 'string'; const wouldSameTypeBeInferred = castType.isLiteral() || - isCastTypeTemplateLiteral || - isCastTypeUnionStringlike + isAssertionTypeTemplateLiteral || + isAssertionTypeUnionStringlike ? isImplicitlyNarrowedConstDeclaration(node) : !isConstAssertion(node.typeAnnotation); From e33c712e026cb4772d94d8868164c16ea9a62b66 Mon Sep 17 00:00:00 2001 From: mdm317 <62943813+mdm317@users.noreply.github.com> Date: Wed, 1 Jan 2025 14:34:26 +0900 Subject: [PATCH 3/4] delete useless noFormat --- .../tests/rules/no-unnecessary-type-assertion.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts index 8d4660cf8c17..a4d34d1881bb 100644 --- a/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts @@ -359,12 +359,12 @@ x!; `, }, "let a = (Date.now() % 2 ? 'a' : 'b') as 'a' | 'b';", - noFormat` - const state: "expired" | "pending" = "pending"; + ` + const state: 'expired' | 'pending' = 'pending'; function main() { return { - type: \`\${state}Request\` as \`\${typeof state}Request\` + type: \`\${state}Request\` as \`\${typeof state}Request\`, }; } `, From a6786eb4c6bac82cdaa828abcef8996e19606abf Mon Sep 17 00:00:00 2001 From: mdm317 Date: Sun, 5 Jan 2025 16:41:55 +0900 Subject: [PATCH 4/4] review: simplify logic --- .../src/rules/no-unnecessary-type-assertion.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts b/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts index 1ea069180ae4..d29bd1292d02 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts @@ -224,16 +224,12 @@ export default createRule({ const castType = services.getTypeAtLocation(node); const uncastType = services.getTypeAtLocation(node.expression); const typeIsUnchanged = isTypeUnchanged(uncastType, castType); - const isAssertionTypeTemplateLiteral = - node.typeAnnotation.type === AST_NODE_TYPES.TSTemplateLiteralType; const isAssertionTypeUnionStringlike = castType.isUnion() && getTypeName(checker, castType) === 'string'; const wouldSameTypeBeInferred = - castType.isLiteral() || - isAssertionTypeTemplateLiteral || - isAssertionTypeUnionStringlike + castType.isLiteral() || isAssertionTypeUnionStringlike ? isImplicitlyNarrowedConstDeclaration(node) : !isConstAssertion(node.typeAnnotation);