@@ -6814,57 +6814,56 @@ namespace ts {
6814
6814
return undefined;
6815
6815
}
6816
6816
6817
- function resolveTypeReferenceName(node: TypeReferenceType, typeReferenceName: EntityNameExpression | EntityName) {
6817
+ function resolveTypeReferenceName(typeReferenceName: EntityNameExpression | EntityName, meaning: SymbolFlags ) {
6818
6818
if (!typeReferenceName) {
6819
6819
return unknownSymbol;
6820
6820
}
6821
6821
6822
- const meaning = node.kind === SyntaxKind.JSDocTypeReference
6823
- ? SymbolFlags.Type | SymbolFlags.Value
6824
- : SymbolFlags.Type;
6825
-
6826
6822
return resolveEntityName(typeReferenceName, meaning) || unknownSymbol;
6827
6823
}
6828
6824
6829
6825
function getTypeReferenceType(node: TypeReferenceType, symbol: Symbol) {
6830
6826
const typeArguments = typeArgumentsFromTypeReferenceNode(node); // Do unconditionally so we mark type arguments as referenced.
6831
- let secondPass = false;
6832
- let fallbackType: Type = unknownType;
6833
- while (true) {
6834
- if (symbol === unknownSymbol) {
6835
- return fallbackType;
6836
- }
6827
+ if (symbol === unknownSymbol) {
6828
+ return unknownType;
6829
+ }
6837
6830
6838
- if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
6839
- return getTypeFromClassOrInterfaceReference(node, symbol, typeArguments);
6840
- }
6831
+ const type = getTypeReferenceTypeWorker(node, symbol, typeArguments);
6832
+ if (type) {
6833
+ return type;
6834
+ }
6841
6835
6842
- if (symbol.flags & SymbolFlags.TypeAlias) {
6843
- return getTypeFromTypeAliasReference(node, symbol, typeArguments);
6836
+ if (symbol.flags & SymbolFlags.Value && node.kind === SyntaxKind.JSDocTypeReference) {
6837
+ // A JSDocTypeReference may have resolved to a value (as opposed to a type). If
6838
+ // the symbol is a constructor function, return the inferred class type; otherwise,
6839
+ // the type of this reference is just the type of the value we resolved to.
6840
+ const valueType = getTypeOfSymbol(symbol);
6841
+ if (valueType.symbol && !isInferredClassType(valueType)) {
6842
+ const referenceType = getTypeReferenceTypeWorker(node, valueType.symbol, typeArguments);
6843
+ if (referenceType) {
6844
+ return referenceType;
6845
+ }
6844
6846
}
6845
6847
6846
- if (symbol.flags & SymbolFlags.Value && node.kind === SyntaxKind.JSDocTypeReference) {
6847
- // A JSDocTypeReference may have resolved to a value (as opposed to a type). If
6848
- // the symbol is a constructor function, return the inferred class type; otherwise,
6849
- // the type of this reference is just the type of the value we resolved to.
6850
- if (symbol.flags & SymbolFlags.Function && (symbol.members || getJSDocClassTag(symbol.valueDeclaration))) {
6851
- return getInferredClassType(symbol);
6852
- }
6848
+ // Resolve the type reference as a Type for the purpose of reporting errors.
6849
+ resolveTypeReferenceName(getTypeReferenceName(node), SymbolFlags.Type);
6850
+ return valueType;
6851
+ }
6853
6852
6854
- // Stop if this is the second pass
6855
- if (secondPass) {
6856
- return fallbackType;
6857
- }
6853
+ return getTypeFromNonGenericTypeReference(node, symbol);
6854
+ }
6858
6855
6859
- // Try to use the symbol of the type (if present) to get a better type on the
6860
- // second pass.
6861
- fallbackType = getTypeOfSymbol(symbol);
6862
- symbol = fallbackType.symbol || unknownSymbol;
6863
- secondPass = true;
6864
- continue;
6865
- }
6856
+ function getTypeReferenceTypeWorker(node: TypeReferenceType, symbol: Symbol, typeArguments: Type[]): Type | undefined {
6857
+ if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
6858
+ return getTypeFromClassOrInterfaceReference(node, symbol, typeArguments);
6859
+ }
6860
+
6861
+ if (symbol.flags & SymbolFlags.TypeAlias) {
6862
+ return getTypeFromTypeAliasReference(node, symbol, typeArguments);
6863
+ }
6866
6864
6867
- return getTypeFromNonGenericTypeReference(node, symbol);
6865
+ if (symbol.flags & SymbolFlags.Function && node.kind === SyntaxKind.JSDocTypeReference && (symbol.members || getJSDocClassTag(symbol.valueDeclaration))) {
6866
+ return getInferredClassType(symbol);
6868
6867
}
6869
6868
}
6870
6869
@@ -6908,11 +6907,13 @@ namespace ts {
6908
6907
if (!links.resolvedType) {
6909
6908
let symbol: Symbol;
6910
6909
let type: Type;
6910
+ let meaning = SymbolFlags.Type;
6911
6911
if (node.kind === SyntaxKind.JSDocTypeReference) {
6912
6912
type = getPrimitiveTypeFromJSDocTypeReference(node);
6913
+ meaning |= SymbolFlags.Value;
6913
6914
}
6914
6915
if (!type) {
6915
- symbol = resolveTypeReferenceName(node, getTypeReferenceName(node));
6916
+ symbol = resolveTypeReferenceName(getTypeReferenceName(node), meaning );
6916
6917
type = getTypeReferenceType(node, symbol);
6917
6918
}
6918
6919
// Cache both the resolved symbol and the resolved type. The resolved symbol is needed in when we check the
@@ -16155,6 +16156,12 @@ namespace ts {
16155
16156
return links.inferredClassType;
16156
16157
}
16157
16158
16159
+ function isInferredClassType(type: Type) {
16160
+ return type.symbol
16161
+ && getObjectFlags(type) & ObjectFlags.Anonymous
16162
+ && getSymbolLinks(type.symbol).inferredClassType === type;
16163
+ }
16164
+
16158
16165
/**
16159
16166
* Syntactically and semantically checks a call or new expression.
16160
16167
* @param node The call/new expression to be checked.
0 commit comments