From 5a9de9281250ebe36935d9ab83715fc6fa6d3028 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 28 Sep 2026 08:26:50 -0700 Subject: [PATCH] Only check properties with multiple declarations for never-reduction --- tsc/internal/checker/checker.go | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/tsc/internal/checker/checker.go b/tsc/internal/checker/checker.go index 845f62365bb84..4cb27ebf27e11 100644 --- a/tsc/internal/checker/checker.go +++ b/tsc/internal/checker/checker.go @@ -22189,7 +22189,7 @@ func (c *Checker) getReducedType(t *Type) *Type { case t.flags&TypeFlagsIntersection != 0: if t.objectFlags&ObjectFlagsIsNeverIntersectionComputed == 0 { t.objectFlags |= ObjectFlagsIsNeverIntersectionComputed - if core.Some(c.getPropertiesOfUnionOrIntersectionType(t), c.isNeverReducedProperty) { + if c.somePropertyReducesToNever(t) { t.objectFlags |= ObjectFlagsIsNeverIntersection } } @@ -22200,6 +22200,25 @@ func (c *Checker) getReducedType(t *Type) *Type { return t } +func (c *Checker) somePropertyReducesToNever(t *Type) bool { + // Collect declaration counts for each property across all constituent types of the intersection. + counts := make(map[string]int) + for _, t := range t.Types() { + for _, prop := range c.getPropertiesOfType(t) { + counts[prop.Name]++ + } + } + // Check if any property appears in more than one constituent type and reduces to 'never'. + for propName, count := range counts { + if count > 1 { + if prop := c.getPropertyOfUnionOrIntersectionType(t, propName, true /*skipObjectFunctionPropertyAugment*/); prop != nil && c.isNeverReducedProperty(prop) { + return true + } + } + } + return false +} + func (c *Checker) getReducedUnionType(unionType *Type) *Type { reducedTypes := core.SameMap(unionType.Types(), c.getReducedType) if core.Same(reducedTypes, unionType.Types()) {