Fix: Correctly flag always-truthy exported and imported enum conditions (ts2845)#4530
Fix: Correctly flag always-truthy exported and imported enum conditions (ts2845)#4530iapoorv01 wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
Adjusts checker control-flow analysis in the TypeScript native port to correctly detect always-truthy enum-member conditions (TS2845) when the enum is exported or referenced through an import alias.
Changes:
- Unwraps alias symbols (
SymbolFlagsAlias) before checking enum-ness for TS2845 suppression logic. - Unwraps exported value symbols (
SymbolFlagsExportValueviagetExportSymbolOfValueSymbolIfExported) to access underlying enum flags.
6e1c618 to
bb5e724
Compare
When an enum is exported or imported, the control flow analysis incorrectly suppressed the ts2845 error (This condition will always return 'true') for known truthy conditions like testing AdapterOutputType.PAGES. This occurred because checkTestingKnownTruthyType failed to resolve the local reference's SymbolFlagsExportValue or SymbolFlagsAlias back to the underlying SymbolFlagsEnum. Since Flags & ast.SymbolFlagsEnum resulted in 0, the check was skipped entirely. This commit introduces resolveAlias and getExportSymbolOfValueSymbolIfExported checks to properly unwrap the symbol and correctly identify the Enum, thus restoring the expected truthiness evaluation logic for open-ended enums. Fixes microsoft/TypeScript#63565
@microsoft-github-policy-service agree |
🚀 Problem Statement
Fixes microsoft/TypeScript#63565.
Currently, the control flow analysis incorrectly suppresses the
ts2845error ("This condition will always return 'true'") for known truthy enum conditions if the enum is declared with theexportmodifier, or if it is imported from another module as an alias. For instance, testingAdapterOutputType.PAGES === 1will fail to emit the error ifAdapterOutputTypeis an exported enum.🕵️ Root Cause Analysis
When testing truthiness in
checkTestingKnownTruthyType, the compiler verifies whether the referenced expression belongs to an enum by checkingSymbolFlagsEnum. However, the current logic only checks the resolved local symbol (c.getResolvedSymbolOrNil(location.Expression())).This check inadvertently drops the
SymbolFlagsEnumtag in two key scenarios:SymbolFlagsExportValue. The actualSymbolFlagsEnumtag is stored in the underlying.ExportSymbol.SymbolFlagsAlias), completely masking the underlying enum flags.As a result,
Flags & ast.SymbolFlagsEnumevaluates to0, the compiler silently assumes it is an open-ended generic property access, and the truthiness validation is pessimistically bypassed.🛠️ The Fix
This PR modifies
internal/checker/checker.go->checkTestingKnownTruthyTypeto properly traverse and unwrap the symbol tree before performing theSymbolFlagsEnumverification:SymbolFlagsAlias(covering cross-module imports).SymbolFlagsExportValueviagetExportSymbolOfValueSymbolIfExportedto reach the true declaration flags.📊 Pros & Cons
ts2845across both local and exported enums without overhauling binding mechanisms.resolveAliasandgetExportSymbolOfValueSymbolIfExported).🧪 Testing
checkTestingKnownTruthyTypecontrol flow pipeline..typesand.errorsbaselines requiresgoto executenpx hereby baseline-acceptnatively.