Skip to content

Commit d3d9175

Browse files
committed
PR Feedback
1 parent 7304a73 commit d3d9175

File tree

1 file changed

+43
-36
lines changed

1 file changed

+43
-36
lines changed

src/compiler/checker.ts

Lines changed: 43 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6814,57 +6814,56 @@ namespace ts {
68146814
return undefined;
68156815
}
68166816

6817-
function resolveTypeReferenceName(node: TypeReferenceType, typeReferenceName: EntityNameExpression | EntityName) {
6817+
function resolveTypeReferenceName(typeReferenceName: EntityNameExpression | EntityName, meaning: SymbolFlags) {
68186818
if (!typeReferenceName) {
68196819
return unknownSymbol;
68206820
}
68216821

6822-
const meaning = node.kind === SyntaxKind.JSDocTypeReference
6823-
? SymbolFlags.Type | SymbolFlags.Value
6824-
: SymbolFlags.Type;
6825-
68266822
return resolveEntityName(typeReferenceName, meaning) || unknownSymbol;
68276823
}
68286824

68296825
function getTypeReferenceType(node: TypeReferenceType, symbol: Symbol) {
68306826
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+
}
68376830

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+
}
68416835

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+
}
68446846
}
68456847

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+
}
68536852

6854-
// Stop if this is the second pass
6855-
if (secondPass) {
6856-
return fallbackType;
6857-
}
6853+
return getTypeFromNonGenericTypeReference(node, symbol);
6854+
}
68586855

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+
}
68666864

6867-
return getTypeFromNonGenericTypeReference(node, symbol);
6865+
if (symbol.flags & SymbolFlags.Function && node.kind === SyntaxKind.JSDocTypeReference && (symbol.members || getJSDocClassTag(symbol.valueDeclaration))) {
6866+
return getInferredClassType(symbol);
68686867
}
68696868
}
68706869

@@ -6908,11 +6907,13 @@ namespace ts {
69086907
if (!links.resolvedType) {
69096908
let symbol: Symbol;
69106909
let type: Type;
6910+
let meaning = SymbolFlags.Type;
69116911
if (node.kind === SyntaxKind.JSDocTypeReference) {
69126912
type = getPrimitiveTypeFromJSDocTypeReference(node);
6913+
meaning |= SymbolFlags.Value;
69136914
}
69146915
if (!type) {
6915-
symbol = resolveTypeReferenceName(node, getTypeReferenceName(node));
6916+
symbol = resolveTypeReferenceName(getTypeReferenceName(node), meaning);
69166917
type = getTypeReferenceType(node, symbol);
69176918
}
69186919
// 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 {
1615516156
return links.inferredClassType;
1615616157
}
1615716158

16159+
function isInferredClassType(type: Type) {
16160+
return type.symbol
16161+
&& getObjectFlags(type) & ObjectFlags.Anonymous
16162+
&& getSymbolLinks(type.symbol).inferredClassType === type;
16163+
}
16164+
1615816165
/**
1615916166
* Syntactically and semantically checks a call or new expression.
1616016167
* @param node The call/new expression to be checked.

0 commit comments

Comments
 (0)