From 1c5b0216d2fa19b352511c490b3a5e90fcf80563 Mon Sep 17 00:00:00 2001 From: yeonjuan Date: Wed, 27 May 2020 01:15:21 +0900 Subject: [PATCH 1/2] fix(eslint-plugin): [no-unnecessary-condition] handling nullable target properly --- .../src/rules/no-unnecessary-condition.ts | 5 +- .../rules/no-unnecessary-condition.test.ts | 57 +++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts index 1c73614c8a77..1ab1309f52cb 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts @@ -20,6 +20,7 @@ import { isNullableType, nullThrows, NullThrowsReasons, + isMemberOrOptionalMemberExpression } from '../util'; const typeContainsFlag = (type: ts.Type, flag: ts.TypeFlags): boolean => { @@ -439,7 +440,9 @@ export default createRule({ return; } - const type = getNodeType(node); + const nodeToCheck = isMemberOrOptionalMemberExpression(node) ? node.object : node; + const type = getNodeType(nodeToCheck); + if ( isTypeFlagSet(type, ts.TypeFlags.Any) || isTypeFlagSet(type, ts.TypeFlags.Unknown) || diff --git a/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts b/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts index 72bf643942fb..d15be4f63a13 100644 --- a/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts @@ -724,5 +724,62 @@ foo }, ], }, + { + code: ` + declare const x: { a?: { b: string } }; + x?.a?.b; + `, + output: ` + declare const x: { a?: { b: string } }; + x.a?.b; + `, + errors: [ + { + messageId: 'neverOptionalChain', + line: 3, + endLine: 3, + column: 12, + endColumn: 14, + } + ], + }, + { + code: ` + declare const x: { a: { b?: { c: string } } }; + x.a?.b?.c; + `, + output: ` + declare const x: { a: { b?: { c: string } } }; + x.a.b?.c; + `, + errors: [ + { + messageId: 'neverOptionalChain', + line: 3, + endLine: 3, + column: 14, + endColumn: 16, + } + ], + }, + { + code: ` + let x: { a?: string }; + x?.a; + `, + output: ` + let x: { a?: string }; + x.a; + `, + errors: [ + { + messageId: 'neverOptionalChain', + line: 3, + endLine: 3, + column: 12, + endColumn: 14, + } + ], + } ], }); From 53a33f23544fbd5224d88bd6f440dda702bf6808 Mon Sep 17 00:00:00 2001 From: yeonjuan Date: Wed, 27 May 2020 01:23:16 +0900 Subject: [PATCH 2/2] fix format --- .../src/rules/no-unnecessary-condition.ts | 6 +- .../rules/no-unnecessary-condition.test.ts | 112 +++++++++--------- 2 files changed, 60 insertions(+), 58 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts index 1ab1309f52cb..316b4fcd76ac 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts @@ -20,7 +20,7 @@ import { isNullableType, nullThrows, NullThrowsReasons, - isMemberOrOptionalMemberExpression + isMemberOrOptionalMemberExpression, } from '../util'; const typeContainsFlag = (type: ts.Type, flag: ts.TypeFlags): boolean => { @@ -440,7 +440,9 @@ export default createRule({ return; } - const nodeToCheck = isMemberOrOptionalMemberExpression(node) ? node.object : node; + const nodeToCheck = isMemberOrOptionalMemberExpression(node) + ? node.object + : node; const type = getNodeType(nodeToCheck); if ( diff --git a/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts b/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts index d15be4f63a13..fa3d1e6fc3b5 100644 --- a/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts @@ -725,61 +725,61 @@ foo ], }, { - code: ` - declare const x: { a?: { b: string } }; - x?.a?.b; - `, - output: ` - declare const x: { a?: { b: string } }; - x.a?.b; - `, - errors: [ - { - messageId: 'neverOptionalChain', - line: 3, - endLine: 3, - column: 12, - endColumn: 14, - } - ], - }, - { - code: ` - declare const x: { a: { b?: { c: string } } }; - x.a?.b?.c; - `, - output: ` - declare const x: { a: { b?: { c: string } } }; - x.a.b?.c; - `, - errors: [ - { - messageId: 'neverOptionalChain', - line: 3, - endLine: 3, - column: 14, - endColumn: 16, - } - ], - }, - { - code: ` - let x: { a?: string }; - x?.a; - `, - output: ` - let x: { a?: string }; - x.a; - `, - errors: [ - { - messageId: 'neverOptionalChain', - line: 3, - endLine: 3, - column: 12, - endColumn: 14, - } - ], - } + code: ` +declare const x: { a?: { b: string } }; +x?.a?.b; + `, + output: ` +declare const x: { a?: { b: string } }; +x.a?.b; + `, + errors: [ + { + messageId: 'neverOptionalChain', + line: 3, + endLine: 3, + column: 2, + endColumn: 4, + }, + ], + }, + { + code: ` +declare const x: { a: { b?: { c: string } } }; +x.a?.b?.c; + `, + output: ` +declare const x: { a: { b?: { c: string } } }; +x.a.b?.c; + `, + errors: [ + { + messageId: 'neverOptionalChain', + line: 3, + endLine: 3, + column: 4, + endColumn: 6, + }, + ], + }, + { + code: ` +let x: { a?: string }; +x?.a; + `, + output: ` +let x: { a?: string }; +x.a; + `, + errors: [ + { + messageId: 'neverOptionalChain', + line: 3, + endLine: 3, + column: 2, + endColumn: 4, + }, + ], + }, ], });