mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 12:51:30 -05:00
Mark type arguments as used even if used in an invalid way
This commit is contained in:
@@ -4714,7 +4714,7 @@ namespace ts {
|
||||
// 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
|
||||
// class and all return the instance type of the class. There is no need for further checks and we can apply the
|
||||
// type arguments in the same manner as a type reference to get the same error reporting experience.
|
||||
baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseConstructorType.symbol);
|
||||
baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseConstructorType.symbol, typeArgumentsFromTypeReferenceNode(baseTypeNode));
|
||||
}
|
||||
else if (baseConstructorType.flags & TypeFlags.Any) {
|
||||
baseType = baseConstructorType;
|
||||
@@ -5238,7 +5238,7 @@ namespace ts {
|
||||
}
|
||||
const baseTypeNode = getBaseTypeNodeOfClass(classType);
|
||||
const isJavaScript = isInJavaScriptFile(baseTypeNode);
|
||||
const typeArguments = map(baseTypeNode.typeArguments, getTypeFromTypeNode);
|
||||
const typeArguments = typeArgumentsFromTypeReferenceNode(baseTypeNode);
|
||||
const typeArgCount = length(typeArguments);
|
||||
const result: Signature[] = [];
|
||||
for (const baseSig of baseSignatures) {
|
||||
@@ -6501,7 +6501,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Get type from reference to class or interface
|
||||
function getTypeFromClassOrInterfaceReference(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference, symbol: Symbol): Type {
|
||||
function getTypeFromClassOrInterfaceReference(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference, symbol: Symbol, typeArgs: Type[]): Type {
|
||||
const type = <InterfaceType>getDeclaredTypeOfSymbol(getMergedSymbol(symbol));
|
||||
const typeParameters = type.localTypeParameters;
|
||||
if (typeParameters) {
|
||||
@@ -6520,7 +6520,7 @@ namespace ts {
|
||||
// In a type reference, the outer type parameters of the referenced class or interface are automatically
|
||||
// supplied as type arguments and the type reference only specifies arguments for the local type parameters
|
||||
// of the class or interface.
|
||||
const typeArguments = concatenate(type.outerTypeParameters, fillMissingTypeArguments(map(node.typeArguments, getTypeFromTypeNode), typeParameters, minTypeArgumentCount, node));
|
||||
const typeArguments = concatenate(type.outerTypeParameters, fillMissingTypeArguments(typeArgs, typeParameters, minTypeArgumentCount, node));
|
||||
return createTypeReference(<GenericType>type, typeArguments);
|
||||
}
|
||||
if (node.typeArguments) {
|
||||
@@ -6545,7 +6545,7 @@ namespace ts {
|
||||
// Get type from reference to type alias. When a type alias is generic, the declared type of the type alias may include
|
||||
// references to the type parameters of the alias. We replace those with the actual type arguments by instantiating the
|
||||
// declared type. Instantiations are cached using the type identities of the type arguments as the key.
|
||||
function getTypeFromTypeAliasReference(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference, symbol: Symbol): Type {
|
||||
function getTypeFromTypeAliasReference(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference, symbol: Symbol, typeArguments: Type[]): Type {
|
||||
const type = getDeclaredTypeOfSymbol(symbol);
|
||||
const typeParameters = getSymbolLinks(symbol).typeParameters;
|
||||
if (typeParameters) {
|
||||
@@ -6561,7 +6561,6 @@ namespace ts {
|
||||
typeParameters.length);
|
||||
return unknownType;
|
||||
}
|
||||
const typeArguments = map(node.typeArguments, getTypeFromTypeNode);
|
||||
return getTypeAliasInstantiation(symbol, typeArguments);
|
||||
}
|
||||
if (node.typeArguments) {
|
||||
@@ -6609,16 +6608,18 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getTypeReferenceType(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference, symbol: Symbol) {
|
||||
const typeArguments = typeArgumentsFromTypeReferenceNode(node); // Do unconditionally so we mark type arguments as referenced.
|
||||
|
||||
if (symbol === unknownSymbol) {
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
|
||||
return getTypeFromClassOrInterfaceReference(node, symbol);
|
||||
return getTypeFromClassOrInterfaceReference(node, symbol, typeArguments);
|
||||
}
|
||||
|
||||
if (symbol.flags & SymbolFlags.TypeAlias) {
|
||||
return getTypeFromTypeAliasReference(node, symbol);
|
||||
return getTypeFromTypeAliasReference(node, symbol, typeArguments);
|
||||
}
|
||||
|
||||
if (symbol.flags & SymbolFlags.Value && node.kind === SyntaxKind.JSDocTypeReference) {
|
||||
@@ -6686,9 +6687,10 @@ namespace ts {
|
||||
? <EntityNameExpression>(<ExpressionWithTypeArguments>node).expression
|
||||
: undefined;
|
||||
symbol = typeNameOrExpression && resolveEntityName(typeNameOrExpression, SymbolFlags.Type) || unknownSymbol;
|
||||
const typeArguments = typeArgumentsFromTypeReferenceNode(node);
|
||||
type = symbol === unknownSymbol ? unknownType :
|
||||
symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface) ? getTypeFromClassOrInterfaceReference(node, symbol) :
|
||||
symbol.flags & SymbolFlags.TypeAlias ? getTypeFromTypeAliasReference(node, symbol) :
|
||||
symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface) ? getTypeFromClassOrInterfaceReference(node, symbol, typeArguments) :
|
||||
symbol.flags & SymbolFlags.TypeAlias ? getTypeFromTypeAliasReference(node, symbol, typeArguments) :
|
||||
getTypeFromNonGenericTypeReference(node, symbol);
|
||||
}
|
||||
// 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 {
|
||||
return links.resolvedType;
|
||||
}
|
||||
|
||||
function typeArgumentsFromTypeReferenceNode(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference): Type[] {
|
||||
return map(node.typeArguments, getTypeFromTypeNode);
|
||||
}
|
||||
|
||||
function getTypeFromTypeQueryNode(node: TypeQueryNode): Type {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
@@ -14303,7 +14309,17 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
|
||||
function callLikeExpressionMayHaveTypeArguments(node: CallLikeExpression): node is CallExpression | NewExpression {
|
||||
return node.kind === SyntaxKind.CallExpression || node.kind === SyntaxKind.NewExpression;
|
||||
}
|
||||
|
||||
function resolveUntypedCall(node: CallLikeExpression): Signature {
|
||||
if (callLikeExpressionMayHaveTypeArguments(node)) {
|
||||
// Check type arguments even though we will give an error that untyped calls may not accept type arguments.
|
||||
// This gets us diagnostics for the type arguments and marks them as referenced.
|
||||
forEach(node.typeArguments, checkSourceElement);
|
||||
}
|
||||
|
||||
if (node.kind === SyntaxKind.TaggedTemplateExpression) {
|
||||
checkExpression((<TaggedTemplateExpression>node).template);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user