From d603a5e9479f1b026eb458ca36e4c5803a9304bd Mon Sep 17 00:00:00 2001 From: Ronen Amiel Date: Fri, 3 Jan 2025 15:43:58 +0200 Subject: [PATCH] don't flag optional chaining for unconstrained type parameters --- .../src/rules/no-unnecessary-condition.ts | 28 ++++++++++--------- .../rules/no-unnecessary-condition.test.ts | 18 ++++++++++++ 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts index 97664597ef6d..1c9c76bfbacf 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts @@ -304,6 +304,19 @@ export default createRule({ ); } + // Conditional is always necessary if it involves: + // `any` or `unknown` or a naked type variable + function isConditionalAlwaysNecessary(type: ts.Type): boolean { + return tsutils + .unionTypeParts(type) + .some( + part => + isTypeAnyType(part) || + isTypeUnknownType(part) || + isTypeFlagSet(part, ts.TypeFlags.TypeVariable), + ); + } + function isNullableMemberExpression( node: TSESTree.MemberExpression, ): boolean { @@ -370,18 +383,7 @@ export default createRule({ const type = getConstrainedTypeAtLocation(services, expression); - // Conditional is always necessary if it involves: - // `any` or `unknown` or a naked type variable - if ( - tsutils - .unionTypeParts(type) - .some( - part => - isTypeAnyType(part) || - isTypeUnknownType(part) || - isTypeFlagSet(part, ts.TypeFlags.TypeVariable), - ) - ) { + if (isConditionalAlwaysNecessary(type)) { return; } let messageId: MessageId | null = null; @@ -813,7 +815,7 @@ export default createRule({ : true; return ( - isTypeFlagSet(type, ts.TypeFlags.Any | ts.TypeFlags.Unknown) || + isConditionalAlwaysNecessary(type) || (isOwnNullable && isNullableType(type)) ); } 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 e199e72fb43d..61bee3988958 100644 --- a/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts @@ -143,6 +143,24 @@ function test(t: T | []) { return t ? 'yes' : 'no'; } `, + ` +function test(arg: T, key: keyof T) { + if (arg[key]?.toString()) { + } +} + `, + ` +function test(arg: T, key: keyof T) { + if (arg?.toString()) { + } +} + `, + ` +function test(arg: T | { value: string }) { + if (arg?.value) { + } +} + `, // Boolean expressions `