@@ -375,7 +375,6 @@ namespace ts {
375375 ResolvedBaseConstructorType,
376376 DeclaredType,
377377 ResolvedReturnType,
378- ResolvedDefault
379378 }
380379
381380 const builtinGlobals = createMap<Symbol>();
@@ -2651,7 +2650,7 @@ namespace ts {
26512650 writeSpace(writer);
26522651 buildTypeDisplay(constraint, writer, enclosingDeclaration, flags, symbolStack);
26532652 }
2654- const defaultType = getDefaultOfTypeParameter (tp);
2653+ const defaultType = getDefaultFromTypeParameter (tp);
26552654 if (defaultType) {
26562655 writeSpace(writer);
26572656 writePunctuation(writer, SyntaxKind.EqualsToken);
@@ -3054,9 +3053,6 @@ namespace ts {
30543053 if (propertyName === TypeSystemPropertyName.ResolvedReturnType) {
30553054 return (<Signature>target).resolvedReturnType;
30563055 }
3057- if (propertyName === TypeSystemPropertyName.ResolvedDefault) {
3058- return (<TypeVariable>target).resolvedDefault;
3059- }
30603056
30613057 Debug.fail("Unhandled TypeSystemPropertyName " + propertyName);
30623058 }
@@ -4863,69 +4859,6 @@ namespace ts {
48634859 return typeParameter.default === noConstraintOrDefaultType ? undefined : typeParameter.default;
48644860 }
48654861
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-
49294862 /**
49304863 * For a type parameter, return the base constraint of the type parameter. For the string, number,
49314864 * boolean, and symbol primitive types, return the corresponding object types. Otherwise return the
@@ -5241,20 +5174,23 @@ namespace ts {
52415174 typeArguments = [];
52425175 }
52435176
5244- // Map an unsatisfied type parameter with a default type to the default type .
5177+ // Map an unsatisfied type parameter with a default type.
52455178 // 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.
52475180 const mapper: TypeMapper = t => {
52485181 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;
52545189 };
52555190
52565191 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;
52585194 }
52595195 }
52605196 }
@@ -9181,8 +9117,16 @@ namespace ts {
91819117 // succeeds, meaning there is no error for not having inference candidates. An
91829118 // inference error only occurs when there are *conflicting* candidates, i.e.
91839119 // 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+
91869130 inferenceSucceeded = true;
91879131 }
91889132 context.inferredTypes[index] = inferredType;
@@ -15574,11 +15518,8 @@ namespace ts {
1557415518 if (!hasNonCircularBaseConstraint(typeParameter)) {
1557515519 error(node.constraint, Diagnostics.Type_parameter_0_has_a_circular_constraint, typeToString(typeParameter));
1557615520 }
15577- if (!hasNonCircularDefault(typeParameter)) {
15578- error(node.default, Diagnostics.Type_parameter_0_has_a_circular_default, typeToString(typeParameter));
15579- }
1558015521 const constraintType = getConstraintOfTypeParameter(typeParameter);
15581- const defaultType = getDefaultOfTypeParameter (typeParameter);
15522+ const defaultType = getDefaultFromTypeParameter (typeParameter);
1558215523 if (constraintType && defaultType) {
1558315524 checkTypeAssignableTo(defaultType, getTypeWithThisArgument(constraintType, defaultType), node.default, Diagnostics.Type_0_does_not_satisfy_the_constraint_1);
1558415525 }
0 commit comments