@@ -16958,12 +16958,23 @@ namespace ts {
16958
16958
if (includeOptional
16959
16959
? !(filteredByApplicability!.flags & TypeFlags.Never)
16960
16960
: isRelatedTo(targetConstraint, sourceKeys)) {
16961
- const typeParameter = getTypeParameterFromMappedType(target);
16962
- const indexingType = filteredByApplicability ? getIntersectionType([filteredByApplicability, typeParameter]) : typeParameter;
16963
- const indexedAccessType = getIndexedAccessType(source, indexingType);
16964
16961
const templateType = getTemplateTypeFromMappedType(target);
16965
- if (result = isRelatedTo(indexedAccessType, templateType, reportErrors)) {
16966
- return result;
16962
+ const typeParameter = getTypeParameterFromMappedType(target);
16963
+
16964
+ // Fastpath: When the template has the form Obj[P] where P is the mapped type parameter, directly compare `source` with `Obj`
16965
+ // to avoid creating the (potentially very large) number of new intermediate types made by manufacturing `source[P]`
16966
+ const nonNullComponent = extractTypesOfKind(templateType, ~TypeFlags.Nullable);
16967
+ if (nonNullComponent.flags & TypeFlags.IndexedAccess && (nonNullComponent as IndexedAccessType).indexType === typeParameter) {
16968
+ if (result = isRelatedTo(source, (nonNullComponent as IndexedAccessType).objectType, reportErrors)) {
16969
+ return result;
16970
+ }
16971
+ }
16972
+ else {
16973
+ const indexingType = filteredByApplicability ? getIntersectionType([filteredByApplicability, typeParameter]) : typeParameter;
16974
+ const indexedAccessType = getIndexedAccessType(source, indexingType);
16975
+ if (result = isRelatedTo(indexedAccessType, templateType, reportErrors)) {
16976
+ return result;
16977
+ }
16967
16978
}
16968
16979
}
16969
16980
originalErrorInfo = errorInfo;
0 commit comments