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