@@ -10774,28 +10774,8 @@ namespace ts {
10774
10774
* Maps forward-references to later types parameters to the empty object type.
10775
10775
* This is used during inference when instantiating type parameter defaults.
10776
10776
*/
10777
- function createBackreferenceMapper(typeParameters: ReadonlyArray<TypeParameter>, index: number): TypeMapper {
10778
- return t => typeParameters.indexOf(t) >= index ? emptyObjectType : t;
10779
- }
10780
-
10781
- function cloneInferenceContext<T extends InferenceContext | undefined>(context: T, extraFlags: InferenceFlags = 0): InferenceContext | T & undefined {
10782
- return context && createInferenceContext(context.typeParameters, context.signature, context.flags | extraFlags, context.compareTypes, context.inferences);
10783
- }
10784
-
10785
- function cloneInferredPartOfContext(context: InferenceContext): InferenceContext | undefined {
10786
- // Filter context to only those parameters which actually have inference candidates
10787
- const params = [];
10788
- const inferences = [];
10789
- for (let i = 0; i < context.typeParameters.length; i++) {
10790
- const info = context.inferences[i];
10791
- if (info.candidates || info.contraCandidates) {
10792
- params.push(context.typeParameters[i]);
10793
- inferences.push(info);
10794
- }
10795
- }
10796
- return params.length ?
10797
- createInferenceContext(params, context.signature, context.flags | InferenceFlags.NoDefault, context.compareTypes, inferences) :
10798
- undefined;
10777
+ function createBackreferenceMapper(context: InferenceContext, index: number): TypeMapper {
10778
+ return t => findIndex(context.inferences, info => info.typeParameter === t) >= index ? emptyObjectType : t;
10799
10779
}
10800
10780
10801
10781
function combineTypeMappers(mapper1: TypeMapper | undefined, mapper2: TypeMapper): TypeMapper;
@@ -14301,13 +14281,27 @@ namespace ts {
14301
14281
}
14302
14282
}
14303
14283
14304
- function createInferenceContext(typeParameters: ReadonlyArray<TypeParameter>, signature: Signature | undefined, flags: InferenceFlags, compareTypes?: TypeComparer, baseInferences?: InferenceInfo[]): InferenceContext {
14284
+ function createInferenceContext(typeParameters: ReadonlyArray<TypeParameter>, signature: Signature | undefined, flags: InferenceFlags, compareTypes?: TypeComparer): InferenceContext {
14285
+ return createInferenceContextWorker(typeParameters.map(createInferenceInfo), signature, flags, compareTypes || compareTypesAssignable);
14286
+ }
14287
+
14288
+ function cloneInferenceContext<T extends InferenceContext | undefined>(context: T, extraFlags: InferenceFlags = 0): InferenceContext | T & undefined {
14289
+ return context && createInferenceContextWorker(map(context.inferences, cloneInferenceInfo), context.signature, context.flags | extraFlags, context.compareTypes);
14290
+ }
14291
+
14292
+ function cloneInferredPartOfContext(context: InferenceContext): InferenceContext | undefined {
14293
+ const inferences = filter(context.inferences, hasInferenceCandidates);
14294
+ return inferences.length ?
14295
+ createInferenceContextWorker(map(inferences, cloneInferenceInfo), context.signature, context.flags, context.compareTypes) :
14296
+ undefined;
14297
+ }
14298
+
14299
+ function createInferenceContextWorker(inferences: InferenceInfo[], signature: Signature | undefined, flags: InferenceFlags, compareTypes: TypeComparer): InferenceContext {
14305
14300
const context: InferenceContext = {
14306
- typeParameters ,
14301
+ inferences ,
14307
14302
signature,
14308
- inferences: baseInferences ? baseInferences.map(cloneInferenceInfo) : typeParameters.map(createInferenceInfo),
14309
14303
flags,
14310
- compareTypes: compareTypes || compareTypesAssignable ,
14304
+ compareTypes,
14311
14305
mapper: t => mapToInferredType(context, t, /*fix*/ true),
14312
14306
nonFixingMapper: t => mapToInferredType(context, t, /*fix*/ false),
14313
14307
};
@@ -15040,10 +15034,7 @@ namespace ts {
15040
15034
if (defaultType) {
15041
15035
// Instantiate the default type. Any forward reference to a type
15042
15036
// parameter should be instantiated to the empty object type.
15043
- inferredType = instantiateType(defaultType,
15044
- combineTypeMappers(
15045
- createBackreferenceMapper(context.typeParameters, index),
15046
- context.nonFixingMapper));
15037
+ inferredType = instantiateType(defaultType, combineTypeMappers(createBackreferenceMapper(context, index), context.nonFixingMapper));
15047
15038
}
15048
15039
else {
15049
15040
inferredType = getDefaultTypeArgumentType(!!(context.flags & InferenceFlags.AnyDefault));
@@ -23476,7 +23467,7 @@ namespace ts {
23476
23467
const strippedType = getOrCreateTypeFromSignature(getSignatureInstantiationWithoutFillingInTypeArguments(signature, uniqueTypeParameters));
23477
23468
// Infer from the stripped expression type to the contextual type starting with an empty
23478
23469
// set of inference candidates.
23479
- const inferences = map(context.typeParameters, createInferenceInfo);
23470
+ const inferences = map(context.inferences, info => createInferenceInfo(info.typeParameter) );
23480
23471
inferTypes(inferences, strippedType, contextualType);
23481
23472
// If we produced some inference candidates and if the type parameters for which we produced
23482
23473
// candidates do not already have existing inferences, we adopt the new inference candidates and
0 commit comments