@@ -16959,12 +16959,23 @@ namespace ts {
16959
16959
if (includeOptional
16960
16960
? !(filteredByApplicability!.flags & TypeFlags.Never)
16961
16961
: isRelatedTo(targetConstraint, sourceKeys)) {
16962
- const typeParameter = getTypeParameterFromMappedType(target);
16963
- const indexingType = filteredByApplicability ? getIntersectionType([filteredByApplicability, typeParameter]) : typeParameter;
16964
- const indexedAccessType = getIndexedAccessType(source, indexingType);
16965
16962
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
+ }
16968
16979
}
16969
16980
}
16970
16981
originalErrorInfo = errorInfo;
0 commit comments