@@ -2560,6 +2560,22 @@ namespace ts {
25602560 return initializer || decl;
25612561 }
25622562
2563+ /**
2564+ * Get the real symbol of a declaration with an expando initializer.
2565+ *
2566+ * Normally, declarations have an associated symbol, but when a declaration has an expando
2567+ * initializer, the expando's symbol is the one that has all the members merged into it.
2568+ */
2569+ function getExpandoSymbol(symbol: Symbol): Symbol | undefined {
2570+ const decl = symbol.valueDeclaration;
2571+ if (!decl || !isInJSFile(decl) || symbol.flags & SymbolFlags.TypeAlias) {
2572+ return undefined;
2573+ }
2574+ const init = isVariableDeclaration(decl) ? getDeclaredExpandoInitializer(decl) : getAssignedExpandoInitializer(decl);
2575+ return init && getSymbolOfNode(init) || undefined;
2576+ }
2577+
2578+
25632579 function resolveExternalModuleName(location: Node, moduleReferenceExpression: Expression, ignoreErrors?: boolean): Symbol | undefined {
25642580 return resolveExternalModuleNameWorker(location, moduleReferenceExpression, ignoreErrors ? undefined : Diagnostics.Cannot_find_module_0);
25652581 }
@@ -9195,10 +9211,13 @@ namespace ts {
91959211 if (symbol === unknownSymbol) {
91969212 return errorType;
91979213 }
9214+ symbol = getExpandoSymbol(symbol) || symbol;
91989215
9199- const type = getTypeReferenceTypeWorker(node, symbol, typeArguments);
9200- if (type) {
9201- return type;
9216+ if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
9217+ return getTypeFromClassOrInterfaceReference(node, symbol, typeArguments);
9218+ }
9219+ if (symbol.flags & SymbolFlags.TypeAlias) {
9220+ return getTypeFromTypeAliasReference(node, symbol, typeArguments);
92029221 }
92039222
92049223 // Get type from reference to named type that cannot be generic (enum or type parameter)
@@ -9209,62 +9228,34 @@ namespace ts {
92099228 errorType;
92109229 }
92119230
9212- if (!(symbol.flags & SymbolFlags.Value && isJSDocTypeReference(node))) {
9213- return errorType;
9214- }
9215-
9216- const jsdocType = getJSDocTypeReference(node, symbol, typeArguments);
9217- if (jsdocType) {
9218- return jsdocType;
9231+ if (symbol.flags & SymbolFlags.Value && isJSDocTypeReference(node)) {
9232+ const jsdocType = getTypeFromJSAlias(node, symbol);
9233+ if (jsdocType) {
9234+ return jsdocType;
9235+ }
9236+ else {
9237+ // Resolve the type reference as a Type for the purpose of reporting errors.
9238+ resolveTypeReferenceName(getTypeReferenceName(node), SymbolFlags.Type);
9239+ return getTypeOfSymbol(symbol);
9240+ }
92199241 }
92209242
9221- // Resolve the type reference as a Type for the purpose of reporting errors.
9222- resolveTypeReferenceName(getTypeReferenceName(node), SymbolFlags.Type);
9223- return getTypeOfSymbol(symbol);
9243+ return errorType;
92249244 }
92259245
92269246 /**
9227- * A jsdoc TypeReference may have resolved to a value (as opposed to a type). If
9228- * the symbol is a constructor function, return the inferred class type; otherwise,
9229- * the type of this reference is just the type of the value we resolved to .
9247+ * A JSdoc TypeReference may be to a value imported from commonjs.
9248+ * These should really be aliases, but this special-case code fakes alias resolution
9249+ * by producing a type from a value.
92309250 */
9231- function getJSDocTypeReference(node: NodeWithTypeArguments, symbol: Symbol, typeArguments: Type[] | undefined): Type | undefined {
9232- // In the case of an assignment of a function expression (binary expressions, variable declarations, etc.), we will get the
9233- // correct instance type for the symbol on the LHS by finding the type for RHS. For example if we want to get the type of the symbol `foo`:
9234- // var foo = function() {}
9235- // We will find the static type of the assigned anonymous function.
9236- const staticType = getTypeOfSymbol(symbol);
9237- const instanceType =
9238- staticType.symbol &&
9239- staticType.symbol !== symbol && // Make sure this is an assignment like expression by checking that symbol -> type -> symbol doesn't roundtrips.
9240- getTypeReferenceTypeWorker(node, staticType.symbol, typeArguments); // Get the instance type of the RHS symbol.
9241- if (instanceType) {
9242- return getSymbolLinks(symbol).resolvedJSDocType = instanceType;
9243- }
9244- }
9245-
9246- function getTypeReferenceTypeWorker(node: NodeWithTypeArguments, symbol: Symbol, typeArguments: Type[] | undefined): Type | undefined {
9247- if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
9248- if (symbol.valueDeclaration && symbol.valueDeclaration.parent && isBinaryExpression(symbol.valueDeclaration.parent)) {
9249- const jsdocType = getJSDocTypeReference(node, symbol, typeArguments);
9250- if (jsdocType) {
9251- return jsdocType;
9252- }
9253- }
9254- return getTypeFromClassOrInterfaceReference(node, symbol, typeArguments);
9255- }
9256-
9257- if (symbol.flags & SymbolFlags.TypeAlias) {
9258- return getTypeFromTypeAliasReference(node, symbol, typeArguments);
9259- }
9260-
9261- if (symbol.flags & SymbolFlags.Function &&
9262- isJSDocTypeReference(node) &&
9263- isJSConstructor(symbol.valueDeclaration)) {
9264- const resolved = resolveStructuredTypeMembers(<ObjectType>getTypeOfSymbol(symbol));
9265- if (resolved.callSignatures.length === 1) {
9266- return getReturnTypeOfSignature(resolved.callSignatures[0]);
9267- }
9251+ function getTypeFromJSAlias(node: NodeWithTypeArguments, symbol: Symbol): Type | undefined {
9252+ const valueType = getTypeOfSymbol(symbol);
9253+ const typeType =
9254+ valueType.symbol &&
9255+ valueType.symbol !== symbol && // Make sure this is a commonjs export by checking that symbol -> type -> symbol doesn't roundtrip.
9256+ getTypeReferenceType(node, valueType.symbol);
9257+ if (typeType) {
9258+ return getSymbolLinks(symbol).resolvedJSDocType = typeType;
92689259 }
92699260 }
92709261
0 commit comments