@@ -9027,7 +9027,7 @@ namespace ts {
90279027
90289028 if (isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined)) return Ternary.True;
90299029
9030- if (getObjectFlags (source) & ObjectFlags.ObjectLiteral && source.flags & TypeFlags.FreshLiteral) {
9030+ if (isObjectLiteralType (source) && source.flags & TypeFlags.FreshLiteral) {
90319031 if (hasExcessProperties(<FreshObjectLiteralType>source, target, reportErrors)) {
90329032 if (reportErrors) {
90339033 reportRelationError(headMessage, source, target);
@@ -9597,15 +9597,15 @@ namespace ts {
95979597 if (relation === identityRelation) {
95989598 return propertiesIdenticalTo(source, target);
95999599 }
9600- const requireOptionalProperties = relation === subtypeRelation && !(getObjectFlags( source) & ObjectFlags.ObjectLiteral );
9600+ const requireOptionalProperties = relation === subtypeRelation && !isObjectLiteralType( source);
96019601 const unmatchedProperty = getUnmatchedProperty(source, target, requireOptionalProperties);
96029602 if (unmatchedProperty) {
96039603 if (reportErrors) {
96049604 reportError(Diagnostics.Property_0_is_missing_in_type_1, symbolToString(unmatchedProperty), typeToString(source));
96059605 }
96069606 return Ternary.False;
96079607 }
9608- if (getObjectFlags (target) & ObjectFlags.ObjectLiteral ) {
9608+ if (isObjectLiteralType (target)) {
96099609 for (const sourceProp of getPropertiesOfType(source)) {
96109610 if (!getPropertyOfObjectType(target, sourceProp.escapedName)) {
96119611 const sourceType = getTypeOfSymbol(sourceProp);
@@ -10439,7 +10439,7 @@ namespace ts {
1043910439 * Leave signatures alone since they are not subject to the check.
1044010440 */
1044110441 function getRegularTypeOfObjectLiteral(type: Type): Type {
10442- if (!(getObjectFlags (type) & ObjectFlags.ObjectLiteral && type.flags & TypeFlags.FreshLiteral)) {
10442+ if (!(isObjectLiteralType (type) && type.flags & TypeFlags.FreshLiteral)) {
1044310443 return type;
1044410444 }
1044510445 const regularType = (<FreshObjectLiteralType>type).regularType;
@@ -10469,7 +10469,7 @@ namespace ts {
1046910469 if (!context.siblings) {
1047010470 const siblings: Type[] = [];
1047110471 for (const type of getSiblingsOfContext(context.parent)) {
10472- if (getObjectFlags (type) & ObjectFlags.ObjectLiteral ) {
10472+ if (isObjectLiteralType (type)) {
1047310473 const prop = getPropertyOfObjectType(type, context.propertyName);
1047410474 if (prop) {
1047510475 forEachType(getTypeOfSymbol(prop), t => siblings.push(t));
@@ -10485,8 +10485,7 @@ namespace ts {
1048510485 if (!context.resolvedPropertyNames) {
1048610486 const names = createMap<boolean>() as UnderscoreEscapedMap<boolean>;
1048710487 for (const t of getSiblingsOfContext(context)) {
10488- const objectFlags = getObjectFlags(t);
10489- if (objectFlags & ObjectFlags.ObjectLiteral && !(objectFlags & ObjectFlags.ContainsSpread)) {
10488+ if (isObjectLiteralType(t) && !(getObjectFlags(t) & ObjectFlags.ContainsSpread)) {
1049010489 for (const prop of getPropertiesOfType(t)) {
1049110490 names.set(prop.escapedName, true);
1049210491 }
@@ -10545,7 +10544,7 @@ namespace ts {
1054510544 if (type.flags & TypeFlags.Nullable) {
1054610545 return anyType;
1054710546 }
10548- if (getObjectFlags (type) & ObjectFlags.ObjectLiteral ) {
10547+ if (isObjectLiteralType (type)) {
1054910548 return getWidenedTypeOfObjectLiteral(type, context);
1055010549 }
1055110550 if (type.flags & TypeFlags.Union) {
@@ -10586,7 +10585,7 @@ namespace ts {
1058610585 }
1058710586 }
1058810587 }
10589- if (getObjectFlags (type) & ObjectFlags.ObjectLiteral ) {
10588+ if (isObjectLiteralType (type)) {
1059010589 for (const p of getPropertiesOfObjectType(type)) {
1059110590 const t = getTypeOfSymbol(p);
1059210591 if (t.flags & TypeFlags.ContainsWideningType) {
@@ -11099,11 +11098,28 @@ namespace ts {
1109911098 return constraint && maybeTypeOfKind(constraint, TypeFlags.Primitive | TypeFlags.Index);
1110011099 }
1110111100
11101+ function isObjectLiteralType(type: Type) {
11102+ return !!(getObjectFlags(type) & ObjectFlags.ObjectLiteral);
11103+ }
11104+
11105+ function widenObjectLiteralCandidates(candidates: Type[]): Type[] {
11106+ if (candidates.length > 1) {
11107+ const objectLiterals = filter(candidates, isObjectLiteralType);
11108+ if (objectLiterals.length) {
11109+ const objectLiteralsType = getWidenedType(getUnionType(objectLiterals, /*subtypeReduction*/ true));
11110+ return concatenate(filter(candidates, t => !isObjectLiteralType(t)), [objectLiteralsType]);
11111+ }
11112+ }
11113+ return candidates;
11114+ }
11115+
1110211116 function getInferredType(context: InferenceContext, index: number): Type {
1110311117 const inference = context.inferences[index];
1110411118 let inferredType = inference.inferredType;
1110511119 if (!inferredType) {
1110611120 if (inference.candidates) {
11121+ // Extract all object literal types and replace them with a single widened and normalized type.
11122+ const candidates = widenObjectLiteralCandidates(inference.candidates);
1110711123 // We widen inferred literal types if
1110811124 // all inferences were made to top-level ocurrences of the type parameter, and
1110911125 // the type parameter has no constraint or its constraint includes no primitive or literal types, and
@@ -11112,7 +11128,7 @@ namespace ts {
1111211128 const widenLiteralTypes = inference.topLevel &&
1111311129 !hasPrimitiveConstraint(inference.typeParameter) &&
1111411130 (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter));
11115- const baseCandidates = widenLiteralTypes ? sameMap(inference. candidates, getWidenedLiteralType) : inference. candidates;
11131+ const baseCandidates = widenLiteralTypes ? sameMap(candidates, getWidenedLiteralType) : candidates;
1111611132 // If all inferences were made from contravariant positions, infer a common subtype. Otherwise, if
1111711133 // union types were requested or if all inferences were made from the return type position, infer a
1111811134 // union type. Otherwise, infer a common supertype.
0 commit comments