@@ -4714,7 +4714,7 @@ namespace ts {
4714
4714
// When base constructor type is a class with no captured type arguments we know that the constructors all have the same type parameters as the
4715
4715
// class and all return the instance type of the class. There is no need for further checks and we can apply the
4716
4716
// type arguments in the same manner as a type reference to get the same error reporting experience.
4717
- baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseConstructorType.symbol);
4717
+ baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseConstructorType.symbol, typeArgumentsFromTypeReferenceNode(baseTypeNode) );
4718
4718
}
4719
4719
else if (baseConstructorType.flags & TypeFlags.Any) {
4720
4720
baseType = baseConstructorType;
@@ -5238,7 +5238,7 @@ namespace ts {
5238
5238
}
5239
5239
const baseTypeNode = getBaseTypeNodeOfClass(classType);
5240
5240
const isJavaScript = isInJavaScriptFile(baseTypeNode);
5241
- const typeArguments = map (baseTypeNode.typeArguments, getTypeFromTypeNode );
5241
+ const typeArguments = typeArgumentsFromTypeReferenceNode (baseTypeNode);
5242
5242
const typeArgCount = length(typeArguments);
5243
5243
const result: Signature[] = [];
5244
5244
for (const baseSig of baseSignatures) {
@@ -6501,7 +6501,7 @@ namespace ts {
6501
6501
}
6502
6502
6503
6503
// Get type from reference to class or interface
6504
- function getTypeFromClassOrInterfaceReference(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference, symbol: Symbol): Type {
6504
+ function getTypeFromClassOrInterfaceReference(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference, symbol: Symbol, typeArgs: Type[] ): Type {
6505
6505
const type = <InterfaceType>getDeclaredTypeOfSymbol(getMergedSymbol(symbol));
6506
6506
const typeParameters = type.localTypeParameters;
6507
6507
if (typeParameters) {
@@ -6520,7 +6520,7 @@ namespace ts {
6520
6520
// In a type reference, the outer type parameters of the referenced class or interface are automatically
6521
6521
// supplied as type arguments and the type reference only specifies arguments for the local type parameters
6522
6522
// of the class or interface.
6523
- const typeArguments = concatenate(type.outerTypeParameters, fillMissingTypeArguments(map(node.typeArguments, getTypeFromTypeNode) , typeParameters, minTypeArgumentCount, node));
6523
+ const typeArguments = concatenate(type.outerTypeParameters, fillMissingTypeArguments(typeArgs , typeParameters, minTypeArgumentCount, node));
6524
6524
return createTypeReference(<GenericType>type, typeArguments);
6525
6525
}
6526
6526
if (node.typeArguments) {
@@ -6545,7 +6545,7 @@ namespace ts {
6545
6545
// Get type from reference to type alias. When a type alias is generic, the declared type of the type alias may include
6546
6546
// references to the type parameters of the alias. We replace those with the actual type arguments by instantiating the
6547
6547
// declared type. Instantiations are cached using the type identities of the type arguments as the key.
6548
- function getTypeFromTypeAliasReference(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference, symbol: Symbol): Type {
6548
+ function getTypeFromTypeAliasReference(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference, symbol: Symbol, typeArguments: Type[] ): Type {
6549
6549
const type = getDeclaredTypeOfSymbol(symbol);
6550
6550
const typeParameters = getSymbolLinks(symbol).typeParameters;
6551
6551
if (typeParameters) {
@@ -6561,7 +6561,6 @@ namespace ts {
6561
6561
typeParameters.length);
6562
6562
return unknownType;
6563
6563
}
6564
- const typeArguments = map(node.typeArguments, getTypeFromTypeNode);
6565
6564
return getTypeAliasInstantiation(symbol, typeArguments);
6566
6565
}
6567
6566
if (node.typeArguments) {
@@ -6609,16 +6608,18 @@ namespace ts {
6609
6608
}
6610
6609
6611
6610
function getTypeReferenceType(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference, symbol: Symbol) {
6611
+ const typeArguments = typeArgumentsFromTypeReferenceNode(node); // Do unconditionally so we mark type arguments as referenced.
6612
+
6612
6613
if (symbol === unknownSymbol) {
6613
6614
return unknownType;
6614
6615
}
6615
6616
6616
6617
if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
6617
- return getTypeFromClassOrInterfaceReference(node, symbol);
6618
+ return getTypeFromClassOrInterfaceReference(node, symbol, typeArguments );
6618
6619
}
6619
6620
6620
6621
if (symbol.flags & SymbolFlags.TypeAlias) {
6621
- return getTypeFromTypeAliasReference(node, symbol);
6622
+ return getTypeFromTypeAliasReference(node, symbol, typeArguments );
6622
6623
}
6623
6624
6624
6625
if (symbol.flags & SymbolFlags.Value && node.kind === SyntaxKind.JSDocTypeReference) {
@@ -6686,9 +6687,10 @@ namespace ts {
6686
6687
? <EntityNameExpression>(<ExpressionWithTypeArguments>node).expression
6687
6688
: undefined;
6688
6689
symbol = typeNameOrExpression && resolveEntityName(typeNameOrExpression, SymbolFlags.Type) || unknownSymbol;
6690
+ const typeArguments = typeArgumentsFromTypeReferenceNode(node);
6689
6691
type = symbol === unknownSymbol ? unknownType :
6690
- symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface) ? getTypeFromClassOrInterfaceReference(node, symbol) :
6691
- symbol.flags & SymbolFlags.TypeAlias ? getTypeFromTypeAliasReference(node, symbol) :
6692
+ symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface) ? getTypeFromClassOrInterfaceReference(node, symbol, typeArguments ) :
6693
+ symbol.flags & SymbolFlags.TypeAlias ? getTypeFromTypeAliasReference(node, symbol, typeArguments ) :
6692
6694
getTypeFromNonGenericTypeReference(node, symbol);
6693
6695
}
6694
6696
// Cache both the resolved symbol and the resolved type. The resolved symbol is needed in when we check the
@@ -6699,6 +6701,10 @@ namespace ts {
6699
6701
return links.resolvedType;
6700
6702
}
6701
6703
6704
+ function typeArgumentsFromTypeReferenceNode(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference): Type[] {
6705
+ return map(node.typeArguments, getTypeFromTypeNode);
6706
+ }
6707
+
6702
6708
function getTypeFromTypeQueryNode(node: TypeQueryNode): Type {
6703
6709
const links = getNodeLinks(node);
6704
6710
if (!links.resolvedType) {
@@ -14303,7 +14309,17 @@ namespace ts {
14303
14309
return true;
14304
14310
}
14305
14311
14312
+ function callLikeExpressionMayHaveTypeArguments(node: CallLikeExpression): node is CallExpression | NewExpression {
14313
+ return node.kind === SyntaxKind.CallExpression || node.kind === SyntaxKind.NewExpression;
14314
+ }
14315
+
14306
14316
function resolveUntypedCall(node: CallLikeExpression): Signature {
14317
+ if (callLikeExpressionMayHaveTypeArguments(node)) {
14318
+ // Check type arguments even though we will give an error that untyped calls may not accept type arguments.
14319
+ // This gets us diagnostics for the type arguments and marks them as referenced.
14320
+ forEach(node.typeArguments, checkSourceElement);
14321
+ }
14322
+
14307
14323
if (node.kind === SyntaxKind.TaggedTemplateExpression) {
14308
14324
checkExpression((<TaggedTemplateExpression>node).template);
14309
14325
}
0 commit comments