@@ -14485,17 +14485,22 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
14485
14485
return getAugmentedPropertiesOfType(unionType);
14486
14486
}
14487
14487
14488
+ const props = getMembersOfUnionOrIntersection(unionType as UnionType);
14489
+ return arrayFrom(props.values());
14490
+ }
14491
+
14492
+ function getMembersOfUnionOrIntersection(type: UnionOrIntersectionType): SymbolTable {
14488
14493
const props = createSymbolTable();
14489
- for (const memberType of types) {
14494
+ for (const memberType of type. types) {
14490
14495
for (const { escapedName } of getAugmentedPropertiesOfType(memberType)) {
14491
14496
if (!props.has(escapedName)) {
14492
- const prop = createUnionOrIntersectionProperty(unionType as UnionType , escapedName);
14497
+ const prop = createUnionOrIntersectionProperty(type , escapedName);
14493
14498
// May be undefined if the property is private
14494
14499
if (prop) props.set(escapedName, prop);
14495
14500
}
14496
14501
}
14497
14502
}
14498
- return arrayFrom( props.values()) ;
14503
+ return props;
14499
14504
}
14500
14505
14501
14506
function getConstraintOfType(type: InstantiableType | UnionOrIntersectionType): Type | undefined {
@@ -21730,6 +21735,22 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
21730
21735
hasSubstitution ||= isNarrowingSubstitutionType(t); // This avoids displaying error messages with types like `T & T` when narrowing a return type
21731
21736
if (hasInstantiable && hasNullableOrEmpty || hasSubstitution) return true;
21732
21737
}
21738
+
21739
+ return false;
21740
+ }
21741
+
21742
+ function isTypeMergeableIntersectionConstituent(type: Type) {
21743
+ if (
21744
+ type.flags === TypeFlags.Object &&
21745
+ !!((type as ObjectType).objectFlags & ObjectFlags.Anonymous) &&
21746
+ !((type as ObjectType).objectFlags & ObjectFlags.Instantiated)
21747
+ ) {
21748
+ if ((type as ObjectType).objectFlags & ObjectFlags.ReverseMapped) {
21749
+ return isTypeMergeableIntersectionConstituent((type as ReverseMappedType).source);
21750
+ }
21751
+
21752
+ return !typeHasCallOrConstructSignatures(type) && getIndexInfosOfType(type).length === 0;
21753
+ }
21733
21754
return false;
21734
21755
}
21735
21756
@@ -22151,12 +22172,19 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
22151
22172
// turn deferred type references into regular type references, simplify indexed access and
22152
22173
// conditional types, and resolve substitution types to either the substitution (on the source
22153
22174
// side) or the type variable (on the target side).
22154
- const source = getNormalizedType(originalSource, /*writing*/ false);
22175
+ let source = getNormalizedType(originalSource, /*writing*/ false);
22155
22176
let target = getNormalizedType(originalTarget, /*writing*/ true);
22156
22177
22157
22178
if (source === target) return Ternary.True;
22158
22179
22159
22180
if (relation === identityRelation) {
22181
+ if (source.flags & TypeFlags.Intersection) {
22182
+ source = mergeIntersectionTypeIfPossible(source as IntersectionType, /*writing*/ false);
22183
+ }
22184
+ if (target.flags & TypeFlags.Intersection) {
22185
+ target = mergeIntersectionTypeIfPossible(target as IntersectionType, /*writing*/ true);
22186
+ }
22187
+
22160
22188
if (source.flags !== target.flags) return Ternary.False;
22161
22189
if (source.flags & TypeFlags.Singleton) return Ternary.True;
22162
22190
traceUnionsOrIntersectionsTooLarge(source, target);
@@ -22244,6 +22272,21 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
22244
22272
return Ternary.False;
22245
22273
}
22246
22274
22275
+ function mergeIntersectionTypeIfPossible(type: IntersectionType, writing: boolean) {
22276
+ if (every(type.types, isTypeMergeableIntersectionConstituent)) {
22277
+ const reduced = getReducedType(type);
22278
+ if (reduced.flags & TypeFlags.Intersection) {
22279
+ type = reduced as IntersectionType;
22280
+ const members = getMembersOfUnionOrIntersection(type);
22281
+ const intersection = createAnonymousType(/*symbol*/ undefined, members, emptyArray, emptyArray, emptyArray);
22282
+ intersection.aliasSymbol = type.aliasSymbol;
22283
+ intersection.aliasTypeArguments = type.aliasTypeArguments;
22284
+ return getNormalizedType(intersection, writing);
22285
+ }
22286
+ }
22287
+ return type;
22288
+ }
22289
+
22247
22290
function reportErrorResults(originalSource: Type, originalTarget: Type, source: Type, target: Type, headMessage: DiagnosticMessage | undefined) {
22248
22291
const sourceHasBase = !!getSingleBaseForNonAugmentingSubtype(originalSource);
22249
22292
const targetHasBase = !!getSingleBaseForNonAugmentingSubtype(originalTarget);
0 commit comments