@@ -6841,21 +6841,46 @@ namespace ts {
68416841 return undefined;
68426842 }
68436843
6844- function resolveTypeReferenceName(typeReferenceName: EntityNameExpression | EntityName) {
6844+ function resolveTypeReferenceName(typeReferenceName: EntityNameExpression | EntityName, meaning: SymbolFlags ) {
68456845 if (!typeReferenceName) {
68466846 return unknownSymbol;
68476847 }
68486848
6849- return resolveEntityName(typeReferenceName, SymbolFlags.Type ) || unknownSymbol;
6849+ return resolveEntityName(typeReferenceName, meaning ) || unknownSymbol;
68506850 }
68516851
68526852 function getTypeReferenceType(node: TypeReferenceType, symbol: Symbol) {
68536853 const typeArguments = typeArgumentsFromTypeReferenceNode(node); // Do unconditionally so we mark type arguments as referenced.
6854-
68556854 if (symbol === unknownSymbol) {
68566855 return unknownType;
68576856 }
68586857
6858+ const type = getTypeReferenceTypeWorker(node, symbol, typeArguments);
6859+ if (type) {
6860+ return type;
6861+ }
6862+
6863+ if (symbol.flags & SymbolFlags.Value && node.kind === SyntaxKind.JSDocTypeReference) {
6864+ // A JSDocTypeReference may have resolved to a value (as opposed to a type). If
6865+ // the symbol is a constructor function, return the inferred class type; otherwise,
6866+ // the type of this reference is just the type of the value we resolved to.
6867+ const valueType = getTypeOfSymbol(symbol);
6868+ if (valueType.symbol && !isInferredClassType(valueType)) {
6869+ const referenceType = getTypeReferenceTypeWorker(node, valueType.symbol, typeArguments);
6870+ if (referenceType) {
6871+ return referenceType;
6872+ }
6873+ }
6874+
6875+ // Resolve the type reference as a Type for the purpose of reporting errors.
6876+ resolveTypeReferenceName(getTypeReferenceName(node), SymbolFlags.Type);
6877+ return valueType;
6878+ }
6879+
6880+ return getTypeFromNonGenericTypeReference(node, symbol);
6881+ }
6882+
6883+ function getTypeReferenceTypeWorker(node: TypeReferenceType, symbol: Symbol, typeArguments: Type[]): Type | undefined {
68596884 if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
68606885 return getTypeFromClassOrInterfaceReference(node, symbol, typeArguments);
68616886 }
@@ -6864,14 +6889,9 @@ namespace ts {
68646889 return getTypeFromTypeAliasReference(node, symbol, typeArguments);
68656890 }
68666891
6867- if (symbol.flags & SymbolFlags.Value && node.kind === SyntaxKind.JSDocTypeReference) {
6868- // A JSDocTypeReference may have resolved to a value (as opposed to a type). In
6869- // that case, the type of this reference is just the type of the value we resolved
6870- // to.
6871- return getTypeOfSymbol(symbol);
6892+ if (symbol.flags & SymbolFlags.Function && node.kind === SyntaxKind.JSDocTypeReference && (symbol.members || getJSDocClassTag(symbol.valueDeclaration))) {
6893+ return getInferredClassType(symbol);
68726894 }
6873-
6874- return getTypeFromNonGenericTypeReference(node, symbol);
68756895 }
68766896
68776897 function getPrimitiveTypeFromJSDocTypeReference(node: JSDocTypeReference): Type {
@@ -6914,22 +6934,13 @@ namespace ts {
69146934 if (!links.resolvedType) {
69156935 let symbol: Symbol;
69166936 let type: Type;
6937+ let meaning = SymbolFlags.Type;
69176938 if (node.kind === SyntaxKind.JSDocTypeReference) {
6918- type = getPrimitiveTypeFromJSDocTypeReference(<JSDocTypeReference>node);
6919- if (!type) {
6920- const typeReferenceName = getTypeReferenceName(node);
6921- symbol = resolveTypeReferenceName(typeReferenceName);
6922- type = getTypeReferenceType(node, symbol);
6923- }
6939+ type = getPrimitiveTypeFromJSDocTypeReference(node);
6940+ meaning |= SymbolFlags.Value;
69246941 }
6925- else {
6926- // We only support expressions that are simple qualified names. For other expressions this produces undefined.
6927- const typeNameOrExpression: EntityNameOrEntityNameExpression = node.kind === SyntaxKind.TypeReference
6928- ? (<TypeReferenceNode>node).typeName
6929- : isEntityNameExpression((<ExpressionWithTypeArguments>node).expression)
6930- ? <EntityNameExpression>(<ExpressionWithTypeArguments>node).expression
6931- : undefined;
6932- symbol = typeNameOrExpression && resolveEntityName(typeNameOrExpression, SymbolFlags.Type) || unknownSymbol;
6942+ if (!type) {
6943+ symbol = resolveTypeReferenceName(getTypeReferenceName(node), meaning);
69336944 type = getTypeReferenceType(node, symbol);
69346945 }
69356946 // Cache both the resolved symbol and the resolved type. The resolved symbol is needed in when we check the
@@ -8058,7 +8069,7 @@ namespace ts {
80588069 const result = createSignature(signature.declaration, freshTypeParameters,
80598070 signature.thisParameter && instantiateSymbol(signature.thisParameter, mapper),
80608071 instantiateList(signature.parameters, mapper, instantiateSymbol),
8061- instantiateType(signature. resolvedReturnType, mapper) ,
8072+ /* resolvedReturnType*/ undefined ,
80628073 freshTypePredicate,
80638074 signature.minArgumentCount, signature.hasRestParameter, signature.hasLiteralTypes);
80648075 result.target = signature;
@@ -16176,6 +16187,12 @@ namespace ts {
1617616187 return links.inferredClassType;
1617716188 }
1617816189
16190+ function isInferredClassType(type: Type) {
16191+ return type.symbol
16192+ && getObjectFlags(type) & ObjectFlags.Anonymous
16193+ && getSymbolLinks(type.symbol).inferredClassType === type;
16194+ }
16195+
1617916196 /**
1618016197 * Syntactically and semantically checks a call or new expression.
1618116198 * @param node The call/new expression to be checked.
@@ -19398,8 +19415,8 @@ namespace ts {
1939819415
1939919416 function checkFunctionDeclaration(node: FunctionDeclaration): void {
1940019417 if (produceDiagnostics) {
19401- checkFunctionOrMethodDeclaration(node) || checkGrammarForGenerator(node) ;
19402-
19418+ checkFunctionOrMethodDeclaration(node);
19419+ checkGrammarForGenerator(node);
1940319420 checkCollisionWithCapturedSuperVariable(node, node.name);
1940419421 checkCollisionWithCapturedThisVariable(node, node.name);
1940519422 checkCollisionWithCapturedNewTargetVariable(node, node.name);
0 commit comments