@@ -4662,10 +4662,6 @@ namespace ts {
46624662 return type.modifiersType;
46634663 }
46644664
4665- function getErasedTemplateTypeFromMappedType(type: MappedType) {
4666- return instantiateType(getTemplateTypeFromMappedType(type), createTypeEraser([getTypeParameterFromMappedType(type)]));
4667- }
4668-
46694665 function isGenericMappedType(type: Type) {
46704666 if (getObjectFlags(type) & ObjectFlags.Mapped) {
46714667 const constraintType = getConstraintTypeFromMappedType(<MappedType>type);
@@ -7765,25 +7761,24 @@ namespace ts {
77657761 return result;
77667762 }
77677763
7768- // A type [P in S]: X is related to a type [P in T]: Y if T is related to S and X is related to Y.
7764+ // A type [P in S]: X is related to a type [Q in T]: Y if T is related to S and X' is
7765+ // related to Y, where X' is an instantiation of X in which P is replaced with Q. Notice
7766+ // that S and T are contra-variant whereas X and Y are co-variant.
77697767 function mappedTypeRelatedTo(source: Type, target: Type, reportErrors: boolean): Ternary {
77707768 if (isGenericMappedType(target)) {
77717769 if (isGenericMappedType(source)) {
7772- let result: Ternary;
7773- if (relation === identityRelation) {
7774- const readonlyMatches = !(<MappedType>source).declaration.readonlyToken === !(<MappedType>target).declaration.readonlyToken;
7775- const optionalMatches = !(<MappedType>source).declaration.questionToken === !(<MappedType>target).declaration.questionToken;
7776- if (readonlyMatches && optionalMatches) {
7777- if (result = isRelatedTo(getConstraintTypeFromMappedType(<MappedType>target), getConstraintTypeFromMappedType(<MappedType>source), reportErrors)) {
7778- return result & isRelatedTo(getErasedTemplateTypeFromMappedType(<MappedType>source), getErasedTemplateTypeFromMappedType(<MappedType>target), reportErrors);
7779- }
7780- }
7781- }
7782- else {
7783- if (relation === comparableRelation || !(<MappedType>source).declaration.questionToken || (<MappedType>target).declaration.questionToken) {
7784- if (result = isRelatedTo(getConstraintTypeFromMappedType(<MappedType>target), getConstraintTypeFromMappedType(<MappedType>source), reportErrors)) {
7785- return result & isRelatedTo(getTemplateTypeFromMappedType(<MappedType>source), getTemplateTypeFromMappedType(<MappedType>target), reportErrors);
7786- }
7770+ const sourceReadonly = !!(<MappedType>source).declaration.readonlyToken;
7771+ const sourceOptional = !!(<MappedType>source).declaration.questionToken;
7772+ const targetReadonly = !!(<MappedType>target).declaration.readonlyToken;
7773+ const targetOptional = !!(<MappedType>target).declaration.questionToken;
7774+ const modifiersRelated = relation === identityRelation ?
7775+ sourceReadonly === targetReadonly && sourceOptional === targetOptional :
7776+ relation === comparableRelation || !sourceOptional || targetOptional;
7777+ if (modifiersRelated) {
7778+ let result: Ternary;
7779+ if (result = isRelatedTo(getConstraintTypeFromMappedType(<MappedType>target), getConstraintTypeFromMappedType(<MappedType>source), reportErrors)) {
7780+ const mapper = createTypeMapper([getTypeParameterFromMappedType(<MappedType>source)], [getTypeParameterFromMappedType(<MappedType>target)]);
7781+ return result & isRelatedTo(instantiateType(getTemplateTypeFromMappedType(<MappedType>source), mapper), getTemplateTypeFromMappedType(<MappedType>target), reportErrors);
77877782 }
77887783 }
77897784 }
0 commit comments