@@ -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;
@@ -26466,6 +26461,7 @@ namespace ts {
26466
26461
if (produceDiagnostics) {
26467
26462
if (node.default) {
26468
26463
seenDefault = true;
26464
+ checkTypeParametersNotReferenced(node.default, typeParameterDeclarations, i);
26469
26465
}
26470
26466
else if (seenDefault) {
26471
26467
error(node, Diagnostics.Required_type_parameters_may_not_follow_optional_type_parameters);
@@ -26480,6 +26476,24 @@ namespace ts {
26480
26476
}
26481
26477
}
26482
26478
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
+
26483
26497
/** Check that type parameter lists are identical across multiple declarations */
26484
26498
function checkTypeParameterListsIdentical(symbol: Symbol) {
26485
26499
if (symbol.declarations.length === 1) {
0 commit comments