@@ -375,7 +375,6 @@ namespace ts {
375
375
ResolvedBaseConstructorType,
376
376
DeclaredType,
377
377
ResolvedReturnType,
378
- ResolvedDefault
379
378
}
380
379
381
380
const builtinGlobals = createMap<Symbol>();
@@ -2651,7 +2650,7 @@ namespace ts {
2651
2650
writeSpace(writer);
2652
2651
buildTypeDisplay(constraint, writer, enclosingDeclaration, flags, symbolStack);
2653
2652
}
2654
- const defaultType = getDefaultOfTypeParameter (tp);
2653
+ const defaultType = getDefaultFromTypeParameter (tp);
2655
2654
if (defaultType) {
2656
2655
writeSpace(writer);
2657
2656
writePunctuation(writer, SyntaxKind.EqualsToken);
@@ -3054,9 +3053,6 @@ namespace ts {
3054
3053
if (propertyName === TypeSystemPropertyName.ResolvedReturnType) {
3055
3054
return (<Signature>target).resolvedReturnType;
3056
3055
}
3057
- if (propertyName === TypeSystemPropertyName.ResolvedDefault) {
3058
- return (<TypeVariable>target).resolvedDefault;
3059
- }
3060
3056
3061
3057
Debug.fail("Unhandled TypeSystemPropertyName " + propertyName);
3062
3058
}
@@ -4863,69 +4859,6 @@ namespace ts {
4863
4859
return typeParameter.default === noConstraintOrDefaultType ? undefined : typeParameter.default;
4864
4860
}
4865
4861
4866
- /**
4867
- * Gets the default type for a type parameter.
4868
- *
4869
- * If the type parameter is the result of an instantiation, this gets the instantiated
4870
- * default type of its target. If the type parameter has no default type, or if the default
4871
- * type circularly references the type parameter, `undefined` is returned.
4872
- *
4873
- * This function *does* perform a circularity check.
4874
- */
4875
- function getDefaultOfTypeParameter(typeParameter: TypeParameter): Type | undefined {
4876
- return hasNonCircularDefault(typeParameter) ? getDefaultFromTypeParameter(typeParameter) : undefined;
4877
- }
4878
-
4879
- /**
4880
- * Determines whether a type parameter has a non-circular default type.
4881
- *
4882
- * Note that this function also returns `true` if a type parameter *does not* have a
4883
- * default type.
4884
- */
4885
- function hasNonCircularDefault(typeParameter: TypeParameter): boolean {
4886
- return getResolvedDefault(typeParameter) !== circularConstraintOrDefaultType;
4887
- }
4888
-
4889
- /**
4890
- * Resolves the default type of a type parameter.
4891
- *
4892
- * If the type parameter has no default, the `noConstraintOrDefaultType` singleton is
4893
- * returned. If the type parameter has a circular default, the
4894
- * `circularConstraintOrDefaultType` singleton is returned.
4895
- */
4896
- function getResolvedDefault(typeParameter: TypeParameter): Type {
4897
- if (!typeParameter.resolvedDefault) {
4898
- if (!pushTypeResolution(typeParameter, TypeSystemPropertyName.ResolvedDefault)) {
4899
- return circularConstraintOrDefaultType;
4900
- }
4901
- const defaultType = getDefaultFromTypeParameter(typeParameter);
4902
- const type = defaultType && getResolvedDefaultWorker(defaultType);
4903
- if (!popTypeResolution()) {
4904
- return typeParameter.resolvedDefault = circularConstraintOrDefaultType;
4905
- }
4906
- typeParameter.resolvedDefault = type || noConstraintOrDefaultType;
4907
- }
4908
- return typeParameter.resolvedDefault;
4909
- }
4910
-
4911
- /**
4912
- * Recursively resolves the default type for a type.
4913
- *
4914
- * If the type is a union or intersection type and any of its constituents is a circular
4915
- * reference, the `circularConstraintOrDefaultType` singleton is returned.
4916
- */
4917
- function getResolvedDefaultWorker(type: Type): Type {
4918
- if (type.flags & TypeFlags.TypeParameter) {
4919
- return getResolvedDefault(<TypeParameter>type);
4920
- }
4921
- if (type.flags & TypeFlags.UnionOrIntersection) {
4922
- const types = map((<UnionOrIntersectionType>type).types, getResolvedDefaultWorker);
4923
- return some(types, x => x === circularConstraintOrDefaultType) ? circularConstraintOrDefaultType :
4924
- type.flags & TypeFlags.Union ? getUnionType(types) : getIntersectionType(types);
4925
- }
4926
- return type;
4927
- }
4928
-
4929
4862
/**
4930
4863
* For a type parameter, return the base constraint of the type parameter. For the string, number,
4931
4864
* boolean, and symbol primitive types, return the corresponding object types. Otherwise return the
@@ -5241,20 +5174,23 @@ namespace ts {
5241
5174
typeArguments = [];
5242
5175
}
5243
5176
5244
- // Map an unsatisfied type parameter with a default type to the default type .
5177
+ // Map an unsatisfied type parameter with a default type.
5245
5178
// If a type parameter does not have a default type, or if the default type
5246
- // is a circular reference, the empty object type is used.
5179
+ // is a forward reference, the empty object type is used.
5247
5180
const mapper: TypeMapper = t => {
5248
5181
const i = indexOf(typeParameters, t);
5249
- return i >= 0
5250
- ? typeArguments[i] || (typeArguments[i] =
5251
- instantiateType(getDefaultOfTypeParameter(typeParameters[i]), mapper) ||
5252
- emptyObjectType)
5253
- : t;
5182
+ if (i >= typeArguments.length) {
5183
+ return emptyObjectType;
5184
+ }
5185
+ if (i >= 0) {
5186
+ return typeArguments[i];
5187
+ }
5188
+ return t;
5254
5189
};
5255
5190
5256
5191
for (let i = numTypeArguments; i < numTypeParameters; i++) {
5257
- instantiateType(typeParameters[i], mapper);
5192
+ const defaultType = getDefaultFromTypeParameter(typeParameters[i]);
5193
+ typeArguments[i] = defaultType ? instantiateType(defaultType, mapper) : emptyObjectType;
5258
5194
}
5259
5195
}
5260
5196
}
@@ -9181,8 +9117,16 @@ namespace ts {
9181
9117
// succeeds, meaning there is no error for not having inference candidates. An
9182
9118
// inference error only occurs when there are *conflicting* candidates, i.e.
9183
9119
// candidates with no common supertype.
9184
- const defaultType = getDefaultOfTypeParameter(context.signature.typeParameters[index]);
9185
- inferredType = defaultType ? instantiateType(defaultType, getInferenceMapper(context)) : emptyObjectType;
9120
+ const defaultType = getDefaultFromTypeParameter(context.signature.typeParameters[index]);
9121
+ if (defaultType) {
9122
+ const backreferenceMapper: TypeMapper = t => indexOf(context.signature.typeParameters, t) >= index ? emptyObjectType : t;
9123
+ const mapper = combineTypeMappers(backreferenceMapper, getInferenceMapper(context));
9124
+ inferredType = instantiateType(defaultType, mapper);
9125
+ }
9126
+ else {
9127
+ inferredType = emptyObjectType;
9128
+ }
9129
+
9186
9130
inferenceSucceeded = true;
9187
9131
}
9188
9132
context.inferredTypes[index] = inferredType;
@@ -15574,11 +15518,8 @@ namespace ts {
15574
15518
if (!hasNonCircularBaseConstraint(typeParameter)) {
15575
15519
error(node.constraint, Diagnostics.Type_parameter_0_has_a_circular_constraint, typeToString(typeParameter));
15576
15520
}
15577
- if (!hasNonCircularDefault(typeParameter)) {
15578
- error(node.default, Diagnostics.Type_parameter_0_has_a_circular_default, typeToString(typeParameter));
15579
- }
15580
15521
const constraintType = getConstraintOfTypeParameter(typeParameter);
15581
- const defaultType = getDefaultOfTypeParameter (typeParameter);
15522
+ const defaultType = getDefaultFromTypeParameter (typeParameter);
15582
15523
if (constraintType && defaultType) {
15583
15524
checkTypeAssignableTo(defaultType, getTypeWithThisArgument(constraintType, defaultType), node.default, Diagnostics.Type_0_does_not_satisfy_the_constraint_1);
15584
15525
}
0 commit comments