@@ -7928,22 +7928,17 @@ namespace ts {
79287928 const numTypeArguments = length(typeArguments);
79297929 if (isJavaScriptImplicitAny || (numTypeArguments >= minTypeArgumentCount && numTypeArguments <= numTypeParameters)) {
79307930 const result = typeArguments ? typeArguments.slice() : [];
7931-
7932- // Map an unsatisfied type parameter with a default type.
7933- // If a type parameter does not have a default type, or if the default type
7934- // is a forward reference, the empty object type is used.
7935- const baseDefaultType = getDefaultTypeArgumentType(isJavaScriptImplicitAny);
7936- const circularityMapper = createTypeMapper(typeParameters!, map(typeParameters!, () => baseDefaultType));
7931+ // Map invalid forward references in default types to the error type
79377932 for (let i = numTypeArguments; i < numTypeParameters; i++) {
7938- result[i] = instantiateType(getConstraintFromTypeParameter(typeParameters![i]) || baseDefaultType, circularityMapper) ;
7933+ result[i] = errorType ;
79397934 }
7935+ const baseDefaultType = getDefaultTypeArgumentType(isJavaScriptImplicitAny);
79407936 for (let i = numTypeArguments; i < numTypeParameters; i++) {
7941- const mapper = createTypeMapper(typeParameters!, result);
79427937 let defaultType = getDefaultFromTypeParameter(typeParameters![i]);
79437938 if (isJavaScriptImplicitAny && defaultType && isTypeIdenticalTo(defaultType, emptyObjectType)) {
79447939 defaultType = anyType;
79457940 }
7946- result[i] = defaultType ? instantiateType(defaultType, mapper ) : baseDefaultType;
7941+ result[i] = defaultType ? instantiateType(defaultType, createTypeMapper(typeParameters!, result) ) : baseDefaultType;
79477942 }
79487943 result.length = typeParameters!.length;
79497944 return result;
@@ -26466,6 +26461,7 @@ namespace ts {
2646626461 if (produceDiagnostics) {
2646726462 if (node.default) {
2646826463 seenDefault = true;
26464+ checkTypeParametersNotReferenced(node.default, typeParameterDeclarations, i);
2646926465 }
2647026466 else if (seenDefault) {
2647126467 error(node, Diagnostics.Required_type_parameters_may_not_follow_optional_type_parameters);
@@ -26480,6 +26476,24 @@ namespace ts {
2648026476 }
2648126477 }
2648226478
26479+ /** Check that type parameter defaults only reference previously declared type parameters */
26480+ function checkTypeParametersNotReferenced(root: TypeNode, typeParameters: ReadonlyArray<TypeParameterDeclaration>, index: number) {
26481+ visit(root);
26482+ function visit(node: Node) {
26483+ if (node.kind === SyntaxKind.TypeReference) {
26484+ const type = getTypeFromTypeReference(<TypeReferenceNode>node);
26485+ if (type.flags & TypeFlags.TypeParameter) {
26486+ for (let i = index; i < typeParameters.length; i++) {
26487+ if (type.symbol === getSymbolOfNode(typeParameters[i])) {
26488+ error(node, Diagnostics.Type_parameter_defaults_can_only_reference_previously_declared_type_parameters);
26489+ }
26490+ }
26491+ }
26492+ }
26493+ forEachChild(node, visit);
26494+ }
26495+ }
26496+
2648326497 /** Check that type parameter lists are identical across multiple declarations */
2648426498 function checkTypeParameterListsIdentical(symbol: Symbol) {
2648526499 if (symbol.declarations.length === 1) {
0 commit comments