@@ -305,7 +305,6 @@ namespace ts {
305
305
let currentNode: Node | undefined;
306
306
307
307
const emptySymbols = createSymbolTable();
308
- const identityMapper: (type: Type) => Type = identity;
309
308
const arrayVariances = [VarianceFlags.Covariant];
310
309
311
310
const compilerOptions = host.getCompilerOptions();
@@ -702,6 +701,10 @@ namespace ts {
702
701
const keyofConstraintType = keyofStringsOnly ? stringType : stringNumberSymbolType;
703
702
const numberOrBigIntType = getUnionType([numberType, bigintType]);
704
703
704
+ const identityMapper: TypeMapper = { kind: TypeMapKind.Function, func: t => t };
705
+ const restrictiveMapper: TypeMapper = { kind: TypeMapKind.Function, func: t => t.flags & TypeFlags.TypeParameter ? getRestrictiveTypeParameter(<TypeParameter>t) : t };
706
+ const permissiveMapper: TypeMapper = { kind: TypeMapKind.Function, func: t => t.flags & TypeFlags.TypeParameter ? wildcardType : t };
707
+
705
708
const emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
706
709
const emptyJsxObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
707
710
emptyJsxObjectType.objectFlags |= ObjectFlags.JsxAttributes;
@@ -4882,7 +4885,7 @@ namespace ts {
4882
4885
const params = getTypeParametersOfClassOrInterface(
4883
4886
parentSymbol.flags & SymbolFlags.Alias ? resolveAlias(parentSymbol) : parentSymbol
4884
4887
);
4885
- typeParameterNodes = mapToTypeNodes(map(params, ( nextSymbol as TransientSymbol).mapper!), context);
4888
+ typeParameterNodes = mapToTypeNodes(map(params, t => getMappedType(t, ( nextSymbol as TransientSymbol).mapper!) ), context);
4886
4889
}
4887
4890
else {
4888
4891
typeParameterNodes = typeParametersToTypeParameterDeclarations(symbol, context);
@@ -13298,30 +13301,36 @@ namespace ts {
13298
13301
return instantiateList<Signature>(signatures, mapper, instantiateSignature);
13299
13302
}
13300
13303
13301
- function makeUnaryTypeMapper(source: Type, target: Type) {
13302
- return (t: Type) => t === source ? target : t;
13304
+ function createTypeMapper(sources: readonly TypeParameter[], targets: readonly Type[] | undefined): TypeMapper {
13305
+ return sources.length === 1 ?
13306
+ makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) :
13307
+ { kind: TypeMapKind.Multiple, sources, targets };
13303
13308
}
13304
13309
13305
- function makeBinaryTypeMapper(source1: Type, target1: Type, source2: Type, target2: Type) {
13306
- return (t: Type) => t === source1 ? target1 : t === source2 ? target2 : t;
13310
+ function getMappedType(type: Type, map: TypeMapper): Type {
13311
+ switch (map.kind) {
13312
+ case TypeMapKind.Single:
13313
+ return type === map.source ? map.target : type;
13314
+ case TypeMapKind.Multiple:
13315
+ const sources = map.sources;
13316
+ const targets = map.targets;
13317
+ for (let i = 0; i < sources.length; i++) {
13318
+ if (type === sources[i]) {
13319
+ return targets ? targets[i] : anyType;
13320
+ }
13321
+ }
13322
+ return type;
13323
+ case TypeMapKind.Function:
13324
+ return map.func(type);
13325
+ }
13307
13326
}
13308
13327
13309
- function makeArrayTypeMapper(sources: readonly Type[], targets: readonly Type[] | undefined) {
13310
- return (t: Type) => {
13311
- for (let i = 0; i < sources.length; i++) {
13312
- if (t === sources[i]) {
13313
- return targets ? targets[i] : anyType;
13314
- }
13315
- }
13316
- return t;
13317
- };
13328
+ function makeUnaryTypeMapper(source: Type, target: Type): TypeMapper {
13329
+ return { kind: TypeMapKind.Single, source, target };
13318
13330
}
13319
13331
13320
- function createTypeMapper(sources: readonly TypeParameter[], targets: readonly Type[] | undefined): TypeMapper {
13321
- Debug.assert(targets === undefined || sources.length === targets.length);
13322
- return sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) :
13323
- sources.length === 2 ? makeBinaryTypeMapper(sources[0], targets ? targets[0] : anyType, sources[1], targets ? targets[1] : anyType) :
13324
- makeArrayTypeMapper(sources, targets);
13332
+ function makeFunctionTypeMapper(func: (t: Type) => Type): TypeMapper {
13333
+ return { kind: TypeMapKind.Function, func };
13325
13334
}
13326
13335
13327
13336
function createTypeEraser(sources: readonly TypeParameter[]): TypeMapper {
@@ -13333,23 +13342,19 @@ namespace ts {
13333
13342
* This is used during inference when instantiating type parameter defaults.
13334
13343
*/
13335
13344
function createBackreferenceMapper(context: InferenceContext, index: number): TypeMapper {
13336
- return t => findIndex(context.inferences, info => info.typeParameter === t) >= index ? unknownType : t;
13345
+ return { kind: TypeMapKind.Function, func: t => findIndex(context.inferences, info => info.typeParameter === t) >= index ? unknownType : t } ;
13337
13346
}
13338
13347
13339
13348
function combineTypeMappers(mapper1: TypeMapper | undefined, mapper2: TypeMapper): TypeMapper;
13340
13349
function combineTypeMappers(mapper1: TypeMapper, mapper2: TypeMapper | undefined): TypeMapper;
13341
13350
function combineTypeMappers(mapper1: TypeMapper, mapper2: TypeMapper): TypeMapper {
13342
13351
if (!mapper1) return mapper2;
13343
13352
if (!mapper2) return mapper1;
13344
- return t => instantiateType(mapper1(t ), mapper2);
13353
+ return makeFunctionTypeMapper( t => instantiateType(getMappedType(t, mapper1 ), mapper2) );
13345
13354
}
13346
13355
13347
13356
function createReplacementMapper(source: Type, target: Type, baseMapper: TypeMapper): TypeMapper {
13348
- return t => t === source ? target : baseMapper(t);
13349
- }
13350
-
13351
- function permissiveMapper(type: Type) {
13352
- return type.flags & TypeFlags.TypeParameter ? wildcardType : type;
13357
+ return makeFunctionTypeMapper(t => t === source ? target : getMappedType(t, baseMapper));
13353
13358
}
13354
13359
13355
13360
function getRestrictiveTypeParameter(tp: TypeParameter) {
@@ -13360,10 +13365,6 @@ namespace ts {
13360
13365
);
13361
13366
}
13362
13367
13363
- function restrictiveMapper(type: Type) {
13364
- return type.flags & TypeFlags.TypeParameter ? getRestrictiveTypeParameter(<TypeParameter>type) : type;
13365
- }
13366
-
13367
13368
function cloneTypeParameter(typeParameter: TypeParameter): TypeParameter {
13368
13369
const result = createTypeParameter(typeParameter.symbol);
13369
13370
result.target = typeParameter;
@@ -13470,7 +13471,8 @@ namespace ts {
13470
13471
// We are instantiating an anonymous type that has one or more type parameters in scope. Apply the
13471
13472
// mapper to the type parameters to produce the effective list of type arguments, and compute the
13472
13473
// instantiation cache key from the type IDs of the type arguments.
13473
- const typeArguments = map(typeParameters, combineTypeMappers(type.mapper, mapper));
13474
+ const combinedMapper = combineTypeMappers(type.mapper, mapper);
13475
+ const typeArguments = map(typeParameters, t => getMappedType(t, combinedMapper));
13474
13476
const id = getTypeListId(typeArguments);
13475
13477
let result = links.instantiations!.get(id);
13476
13478
if (!result) {
@@ -13615,7 +13617,7 @@ namespace ts {
13615
13617
// We are instantiating a conditional type that has one or more type parameters in scope. Apply the
13616
13618
// mapper to the type parameters to produce the effective list of type arguments, and compute the
13617
13619
// instantiation cache key from the type IDs of the type arguments.
13618
- const typeArguments = map(root.outerTypeParameters, mapper);
13620
+ const typeArguments = map(root.outerTypeParameters, t => getMappedType(t, mapper) );
13619
13621
const id = getTypeListId(typeArguments);
13620
13622
let result = root.instantiations!.get(id);
13621
13623
if (!result) {
@@ -13634,7 +13636,7 @@ namespace ts {
13634
13636
// type A | B, we produce (A extends U ? X : Y) | (B extends U ? X : Y).
13635
13637
if (root.isDistributive) {
13636
13638
const checkType = <TypeParameter>root.checkType;
13637
- const instantiatedType = mapper (checkType);
13639
+ const instantiatedType = getMappedType (checkType, mapper );
13638
13640
if (checkType !== instantiatedType && instantiatedType.flags & (TypeFlags.Union | TypeFlags.Never)) {
13639
13641
return mapType(instantiatedType, t => getConditionalType(root, createReplacementMapper(checkType, t, mapper)));
13640
13642
}
@@ -13665,7 +13667,7 @@ namespace ts {
13665
13667
function instantiateTypeWorker(type: Type, mapper: TypeMapper): Type {
13666
13668
const flags = type.flags;
13667
13669
if (flags & TypeFlags.TypeParameter) {
13668
- return mapper (type);
13670
+ return getMappedType (type, mapper );
13669
13671
}
13670
13672
if (flags & TypeFlags.Object) {
13671
13673
const objectFlags = (<ObjectType>type).objectFlags;
@@ -15430,10 +15432,10 @@ namespace ts {
15430
15432
// We're in the middle of variance checking - integrate any unmeasurable/unreliable flags from this cached component
15431
15433
const saved = entry & RelationComparisonResult.ReportsMask;
15432
15434
if (saved & RelationComparisonResult.ReportsUnmeasurable) {
15433
- instantiateType(source, reportUnmeasurableMarkers);
15435
+ instantiateType(source, makeFunctionTypeMapper( reportUnmeasurableMarkers) );
15434
15436
}
15435
15437
if (saved & RelationComparisonResult.ReportsUnreliable) {
15436
- instantiateType(source, reportUnreliableMarkers);
15438
+ instantiateType(source, makeFunctionTypeMapper( reportUnreliableMarkers) );
15437
15439
}
15438
15440
}
15439
15441
return entry & RelationComparisonResult.Succeeded ? Ternary.True : Ternary.False;
@@ -15878,7 +15880,7 @@ namespace ts {
15878
15880
if (modifiersRelated) {
15879
15881
let result: Ternary;
15880
15882
const targetConstraint = getConstraintTypeFromMappedType(target);
15881
- const sourceConstraint = instantiateType(getConstraintTypeFromMappedType(source), getCombinedMappedTypeOptionality(source) < 0 ? reportUnmeasurableMarkers : reportUnreliableMarkers);
15883
+ const sourceConstraint = instantiateType(getConstraintTypeFromMappedType(source), makeFunctionTypeMapper( getCombinedMappedTypeOptionality(source) < 0 ? reportUnmeasurableMarkers : reportUnreliableMarkers) );
15882
15884
if (result = isRelatedTo(targetConstraint, sourceConstraint, reportErrors)) {
15883
15885
const mapper = createTypeMapper([getTypeParameterFromMappedType(source)], [getTypeParameterFromMappedType(target)]);
15884
15886
return result & isRelatedTo(instantiateType(getTemplateTypeFromMappedType(source), mapper), getTemplateTypeFromMappedType(target), reportErrors);
@@ -16359,7 +16361,7 @@ namespace ts {
16359
16361
*/
16360
16362
function signatureRelatedTo(source: Signature, target: Signature, erase: boolean, reportErrors: boolean, incompatibleReporter: (source: Type, target: Type) => void): Ternary {
16361
16363
return compareSignaturesRelated(erase ? getErasedSignature(source) : source, erase ? getErasedSignature(target) : target,
16362
- relation === strictSubtypeRelation ? SignatureCheckMode.StrictArity : 0, reportErrors, reportError, incompatibleReporter, isRelatedTo, reportUnreliableMarkers);
16364
+ relation === strictSubtypeRelation ? SignatureCheckMode.StrictArity : 0, reportErrors, reportError, incompatibleReporter, isRelatedTo, makeFunctionTypeMapper( reportUnreliableMarkers) );
16363
16365
}
16364
16366
16365
16367
function signaturesIdenticalTo(source: Type, target: Type, kind: SignatureKind): Ternary {
@@ -17556,8 +17558,8 @@ namespace ts {
17556
17558
signature,
17557
17559
flags,
17558
17560
compareTypes,
17559
- mapper: t => mapToInferredType(context, t, /*fix*/ true),
17560
- nonFixingMapper: t => mapToInferredType(context, t, /*fix*/ false),
17561
+ mapper: makeFunctionTypeMapper( t => mapToInferredType(context, t, /*fix*/ true) ),
17562
+ nonFixingMapper: makeFunctionTypeMapper( t => mapToInferredType(context, t, /*fix*/ false) ),
17561
17563
};
17562
17564
return context;
17563
17565
}
0 commit comments