@@ -6382,15 +6382,14 @@ namespace ts {
63826382 return type.resolvedBaseTypes = emptyArray;
63836383 }
63846384 const baseTypeNode = getBaseTypeNodeOfClass(type)!;
6385- const typeArgs = typeArgumentsFromTypeReferenceNode(baseTypeNode);
63866385 let baseType: Type;
63876386 const originalBaseType = baseConstructorType.symbol ? getDeclaredTypeOfSymbol(baseConstructorType.symbol) : undefined;
63886387 if (baseConstructorType.symbol && baseConstructorType.symbol.flags & SymbolFlags.Class &&
63896388 areAllOuterTypeParametersApplied(originalBaseType!)) {
63906389 // 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
63916390 // class and all return the instance type of the class. There is no need for further checks and we can apply the
63926391 // type arguments in the same manner as a type reference to get the same error reporting experience.
6393- baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseConstructorType.symbol, typeArgs );
6392+ baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseConstructorType.symbol);
63946393 }
63956394 else if (baseConstructorType.flags & TypeFlags.Any) {
63966395 baseType = baseConstructorType;
@@ -9115,7 +9114,7 @@ namespace ts {
91159114 return type;
91169115 }
91179116
9118- function createDeferredTypeReference(target: GenericType, node: ArrayTypeNode | TupleTypeNode, mapper?: TypeMapper): DeferredTypeReference {
9117+ function createDeferredTypeReference(target: GenericType, node: TypeReferenceNode | ArrayTypeNode | TupleTypeNode, mapper?: TypeMapper): DeferredTypeReference {
91199118 const aliasSymbol = getAliasSymbolForTypeNode(node);
91209119 const aliasTypeArguments = getTypeArgumentsForAliasSymbol(aliasSymbol);
91219120 const type = <DeferredTypeReference>createObjectType(ObjectFlags.Reference, target.symbol);
@@ -9129,7 +9128,11 @@ namespace ts {
91299128
91309129 function getTypeArguments(type: TypeReference): ReadonlyArray<Type> {
91319130 if (!type.resolvedTypeArguments) {
9132- const typeArguments = type.node ? map(type.node.kind === SyntaxKind.ArrayType ? [type.node.elementType] : type.node.elementTypes, getTypeFromTypeNode) : emptyArray;
9131+ const node = type.node;
9132+ const typeArguments = !node ? emptyArray :
9133+ node.kind === SyntaxKind.TypeReference ? concatenate(type.target.outerTypeParameters, getEffectiveTypeArguments(node, type.target.localTypeParameters!)) :
9134+ node.kind === SyntaxKind.ArrayType ? [getTypeFromTypeNode(node.elementType)] :
9135+ map(node.elementTypes, getTypeFromTypeNode);
91339136 type.resolvedTypeArguments = type.mapper ? instantiateTypes(typeArguments, type.mapper) : typeArguments;
91349137 }
91359138 return type.resolvedTypeArguments;
@@ -9139,10 +9142,11 @@ namespace ts {
91399142 return length(type.target.typeParameters);
91409143 }
91419144
9145+
91429146 /**
91439147 * Get type from type-reference that reference to class or interface
91449148 */
9145- function getTypeFromClassOrInterfaceReference(node: NodeWithTypeArguments, symbol: Symbol, typeArgs: Type[] | undefined ): Type {
9149+ function getTypeFromClassOrInterfaceReference(node: NodeWithTypeArguments, symbol: Symbol): Type {
91469150 const type = <InterfaceType>getDeclaredTypeOfSymbol(getMergedSymbol(symbol));
91479151 const typeParameters = type.localTypeParameters;
91489152 if (typeParameters) {
@@ -9166,10 +9170,13 @@ namespace ts {
91669170 return errorType;
91679171 }
91689172 }
9173+ if (node.kind === SyntaxKind.TypeReference && isAliasedType(node)) {
9174+ return createDeferredTypeReference(<GenericType>type, <TypeReferenceNode>node, /*mapper*/ undefined);
9175+ }
91699176 // In a type reference, the outer type parameters of the referenced class or interface are automatically
91709177 // supplied as type arguments and the type reference only specifies arguments for the local type parameters
91719178 // of the class or interface.
9172- const typeArguments = concatenate(type.outerTypeParameters, fillMissingTypeArguments(typeArgs , typeParameters, minTypeArgumentCount, isJs));
9179+ const typeArguments = concatenate(type.outerTypeParameters, fillMissingTypeArguments(typeArgumentsFromTypeReferenceNode(node) , typeParameters, minTypeArgumentCount, isJs));
91739180 return createTypeReference(<GenericType>type, typeArguments);
91749181 }
91759182 return checkNoTypeArguments(node, symbol) ? type : errorType;
@@ -9192,7 +9199,7 @@ namespace ts {
91929199 * references to the type parameters of the alias. We replace those with the actual type arguments by instantiating the
91939200 * declared type. Instantiations are cached using the type identities of the type arguments as the key.
91949201 */
9195- function getTypeFromTypeAliasReference(node: NodeWithTypeArguments, symbol: Symbol, typeArguments: Type[] | undefined ): Type {
9202+ function getTypeFromTypeAliasReference(node: NodeWithTypeArguments, symbol: Symbol): Type {
91969203 const type = getDeclaredTypeOfSymbol(symbol);
91979204 const typeParameters = getSymbolLinks(symbol).typeParameters;
91989205 if (typeParameters) {
@@ -9208,7 +9215,7 @@ namespace ts {
92089215 typeParameters.length);
92099216 return errorType;
92109217 }
9211- return getTypeAliasInstantiation(symbol, typeArguments );
9218+ return getTypeAliasInstantiation(symbol, typeArgumentsFromTypeReferenceNode(node) );
92129219 }
92139220 return checkNoTypeArguments(node, symbol) ? type : errorType;
92149221 }
@@ -9239,27 +9246,23 @@ namespace ts {
92399246 }
92409247
92419248 function getTypeReferenceType(node: NodeWithTypeArguments, symbol: Symbol): Type {
9242- const typeArguments = typeArgumentsFromTypeReferenceNode(node); // Do unconditionally so we mark type arguments as referenced.
92439249 if (symbol === unknownSymbol) {
92449250 return errorType;
92459251 }
92469252 symbol = getExpandoSymbol(symbol) || symbol;
9247-
92489253 if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
9249- return getTypeFromClassOrInterfaceReference(node, symbol, typeArguments );
9254+ return getTypeFromClassOrInterfaceReference(node, symbol);
92509255 }
92519256 if (symbol.flags & SymbolFlags.TypeAlias) {
9252- return getTypeFromTypeAliasReference(node, symbol, typeArguments );
9257+ return getTypeFromTypeAliasReference(node, symbol);
92539258 }
9254-
92559259 // Get type from reference to named type that cannot be generic (enum or type parameter)
92569260 const res = tryGetDeclaredTypeOfSymbol(symbol);
92579261 if (res) {
92589262 return checkNoTypeArguments(node, symbol) ?
92599263 res.flags & TypeFlags.TypeParameter ? getConstrainedTypeVariable(<TypeParameter>res, node) : getRegularTypeOfLiteralType(res) :
92609264 errorType;
92619265 }
9262-
92639266 if (symbol.flags & SymbolFlags.Value && isJSDocTypeReference(node)) {
92649267 const jsdocType = getTypeFromJSAlias(node, symbol);
92659268 if (jsdocType) {
@@ -9271,7 +9274,6 @@ namespace ts {
92719274 return getTypeOfSymbol(symbol);
92729275 }
92739276 }
9274-
92759277 return errorType;
92769278 }
92779279
@@ -26100,16 +26102,13 @@ namespace ts {
2610026102 if (node.kind === SyntaxKind.TypeReference && node.typeName.jsdocDotPos !== undefined && !isInJSFile(node) && !isInJSDoc(node)) {
2610126103 grammarErrorAtPos(node, node.typeName.jsdocDotPos, 1, Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments);
2610226104 }
26105+ forEach(node.typeArguments, checkSourceElement);
2610326106 const type = getTypeFromTypeReference(node);
2610426107 if (type !== errorType) {
26105- if (node.typeArguments) {
26106- // Do type argument local checks only if referenced type is successfully resolved
26107- forEach(node.typeArguments, checkSourceElement);
26108- if (produceDiagnostics) {
26109- const typeParameters = getTypeParametersForTypeReference(node);
26110- if (typeParameters) {
26111- checkTypeArgumentConstraints(node, typeParameters);
26112- }
26108+ if (node.typeArguments && produceDiagnostics) {
26109+ const typeParameters = getTypeParametersForTypeReference(node);
26110+ if (typeParameters) {
26111+ checkTypeArgumentConstraints(node, typeParameters);
2611326112 }
2611426113 }
2611526114 if (type.flags & TypeFlags.Enum && getNodeLinks(node).resolvedSymbol!.flags & SymbolFlags.EnumMember) {
@@ -29333,6 +29332,7 @@ namespace ts {
2933329332
2933429333 const baseTypeNode = getEffectiveBaseTypeNode(node);
2933529334 if (baseTypeNode) {
29335+ forEach(baseTypeNode.typeArguments, checkSourceElement);
2933629336 if (languageVersion < ScriptTarget.ES2015) {
2933729337 checkExternalEmitHelpers(baseTypeNode.parent, ExternalEmitHelpers.Extends);
2933829338 }
0 commit comments