@@ -7928,22 +7928,17 @@ namespace ts {
7928
7928
const numTypeArguments = length(typeArguments);
7929
7929
if (isJavaScriptImplicitAny || (numTypeArguments >= minTypeArgumentCount && numTypeArguments <= numTypeParameters)) {
7930
7930
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
7937
7932
for (let i = numTypeArguments; i < numTypeParameters; i++) {
7938
- result[i] = instantiateType(getConstraintFromTypeParameter(typeParameters![i]) || baseDefaultType, circularityMapper) ;
7933
+ result[i] = errorType ;
7939
7934
}
7935
+ const baseDefaultType = getDefaultTypeArgumentType(isJavaScriptImplicitAny);
7940
7936
for (let i = numTypeArguments; i < numTypeParameters; i++) {
7941
- const mapper = createTypeMapper(typeParameters!, result);
7942
7937
let defaultType = getDefaultFromTypeParameter(typeParameters![i]);
7943
7938
if (isJavaScriptImplicitAny && defaultType && isTypeIdenticalTo(defaultType, emptyObjectType)) {
7944
7939
defaultType = anyType;
7945
7940
}
7946
- result[i] = defaultType ? instantiateType(defaultType, mapper ) : baseDefaultType;
7941
+ result[i] = defaultType ? instantiateType(defaultType, createTypeMapper(typeParameters!, result) ) : baseDefaultType;
7947
7942
}
7948
7943
result.length = typeParameters!.length;
7949
7944
return result;
@@ -26465,6 +26460,7 @@ namespace ts {
26465
26460
if (produceDiagnostics) {
26466
26461
if (node.default) {
26467
26462
seenDefault = true;
26463
+ checkTypeParametersNotReferenced(node.default, typeParameterDeclarations, i);
26468
26464
}
26469
26465
else if (seenDefault) {
26470
26466
error(node, Diagnostics.Required_type_parameters_may_not_follow_optional_type_parameters);
@@ -26479,6 +26475,24 @@ namespace ts {
26479
26475
}
26480
26476
}
26481
26477
26478
+ /** Check that type parameter defaults only reference previously declared type parameters */
26479
+ function checkTypeParametersNotReferenced(root: TypeNode, typeParameters: ReadonlyArray<TypeParameterDeclaration>, index: number) {
26480
+ visit(root);
26481
+ function visit(node: Node) {
26482
+ if (node.kind === SyntaxKind.TypeReference) {
26483
+ const type = getTypeFromTypeReference(<TypeReferenceNode>node);
26484
+ if (type.flags & TypeFlags.TypeParameter) {
26485
+ for (let i = index; i < typeParameters.length; i++) {
26486
+ if (type.symbol === getSymbolOfNode(typeParameters[i])) {
26487
+ error(node, Diagnostics.Type_parameter_defaults_can_only_reference_previously_declared_type_parameters);
26488
+ }
26489
+ }
26490
+ }
26491
+ }
26492
+ forEachChild(node, visit);
26493
+ }
26494
+ }
26495
+
26482
26496
/** Check that type parameter lists are identical across multiple declarations */
26483
26497
function checkTypeParameterListsIdentical(symbol: Symbol) {
26484
26498
if (symbol.declarations.length === 1) {
0 commit comments