Skip to content

Commit d7a80c4

Browse files
committed
Broaden rule that ensures { [x: string]: xxx } <: {} and not vice-versa
1 parent 7d8fdc8 commit d7a80c4

File tree

1 file changed

+7
-7
lines changed

1 file changed

+7
-7
lines changed

src/compiler/checker.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -21329,11 +21329,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2132921329
return Ternary.False;
2133021330
}
2133121331
}
21332-
// A fresh empty object type is never a subtype of a non-empty object type and an empty object type is never a subtype of
21333-
// a non-empty object type. This ensures fresh({}) <: { [x: string]: xxx } and { [x: string: xxx] } <: {}. Without these
21334-
// rules, those types would be mutual subtypes.
21335-
else if ((relation === subtypeRelation || relation === strictSubtypeRelation) && isEmptyObjectType(target) && getObjectFlags(target) & ObjectFlags.FreshLiteral && !isEmptyObjectType(source) ||
21336-
(relation === strictSubtypeRelation && target.flags & TypeFlags.Object && !isEmptyObjectType(target) && isEmptyObjectType(source) && !(getObjectFlags(source) & ObjectFlags.FreshLiteral))) {
21332+
// A fresh empty object type is never a subtype of a non-empty object type. This ensures fresh({}) <: { [x: string]: xxx }
21333+
// but not vice-versa. Without this rule, those types would be mutual subtypes.
21334+
else if ((relation === subtypeRelation || relation === strictSubtypeRelation) && isEmptyObjectType(target) && getObjectFlags(target) & ObjectFlags.FreshLiteral && !isEmptyObjectType(source)) {
2133721335
return Ternary.False;
2133821336
}
2133921337
// Even if relationship doesn't hold for unions, intersections, or generic type references,
@@ -22084,8 +22082,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2208422082
if (sourceInfo) {
2208522083
return indexInfoRelatedTo(sourceInfo, targetInfo, reportErrors);
2208622084
}
22087-
if (!(intersectionState & IntersectionState.Source) && isObjectTypeWithInferableIndex(source)) {
22088-
// Intersection constituents are never considered to have an inferred index signature
22085+
// Intersection constituents are never considered to have an inferred index signature. Also, in the strict subtype relation,
22086+
// only fresh object literals are considered to have inferred index signatures. This ensures { [x: string]: xxx } <: {} but
22087+
// not vice-versa. Without this rule, those types would be mutual strict subtypes.
22088+
if (!(intersectionState & IntersectionState.Source) && (relation !== strictSubtypeRelation || getObjectFlags(source) & ObjectFlags.FreshLiteral) && isObjectTypeWithInferableIndex(source)) {
2208922089
return membersRelatedToIndexInfo(source, targetInfo, reportErrors, intersectionState);
2209022090
}
2209122091
if (reportErrors) {

0 commit comments

Comments
 (0)