@@ -529,6 +529,11 @@ namespace ts {
529529 Strict,
530530 }
531531
532+ const enum MappedTypeModifiers {
533+ Readonly = 1 << 0,
534+ Optional = 1 << 1,
535+ }
536+
532537 const builtinGlobals = createSymbolTable();
533538 builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol);
534539
@@ -5875,6 +5880,17 @@ namespace ts {
58755880 return type.modifiersType;
58765881 }
58775882
5883+ function getMappedTypeModifiers(type: MappedType): MappedTypeModifiers {
5884+ return (type.declaration.readonlyToken ? MappedTypeModifiers.Readonly : 0) |
5885+ (type.declaration.questionToken ? MappedTypeModifiers.Optional : 0);
5886+ }
5887+
5888+ function getCombinedMappedTypeModifiers(type: MappedType): MappedTypeModifiers {
5889+ const modifiersType = getModifiersTypeFromMappedType(type);
5890+ return getMappedTypeModifiers(type) |
5891+ (isGenericMappedType(modifiersType) ? getMappedTypeModifiers(<MappedType>modifiersType) : 0);
5892+ }
5893+
58785894 function isPartialMappedType(type: Type) {
58795895 return getObjectFlags(type) & ObjectFlags.Mapped && !!(<MappedType>type).declaration.questionToken;
58805896 }
@@ -9592,13 +9608,10 @@ namespace ts {
95929608 // related to Y, where X' is an instantiation of X in which P is replaced with Q. Notice
95939609 // that S and T are contra-variant whereas X and Y are co-variant.
95949610 function mappedTypeRelatedTo(source: MappedType, target: MappedType, reportErrors: boolean): Ternary {
9595- const sourceReadonly = !!source.declaration.readonlyToken;
9596- const sourceOptional = !!source.declaration.questionToken;
9597- const targetReadonly = !!target.declaration.readonlyToken;
9598- const targetOptional = !!target.declaration.questionToken;
9599- const modifiersRelated = relation === identityRelation ?
9600- sourceReadonly === targetReadonly && sourceOptional === targetOptional :
9601- relation === comparableRelation || !sourceOptional || targetOptional;
9611+ const modifiersRelated = relation === comparableRelation || (
9612+ relation === identityRelation ? getMappedTypeModifiers(source) === getMappedTypeModifiers(target) :
9613+ !(getCombinedMappedTypeModifiers(source) & MappedTypeModifiers.Optional) ||
9614+ getCombinedMappedTypeModifiers(target) & MappedTypeModifiers.Optional);
96029615 if (modifiersRelated) {
96039616 let result: Ternary;
96049617 if (result = isRelatedTo(getConstraintTypeFromMappedType(<MappedType>target), getConstraintTypeFromMappedType(<MappedType>source), reportErrors)) {
0 commit comments