JS:resolve nested static classes+on func/class exps

1. In Javascript, support type references to class expressions whose
name is obtained via "static property assignment" to another class like
so:

```ts
function Outer() {
  this.y = 2
}
Outer.Inner = class { }

/** @type {Outer.Inner} */
var inner;
```

2. In Javascript, support type references to properties of function and
class expressions that are assigned to a variable, like so:

```ts
var Outer = function {
  this.y = 2
}
Outer.Inner = class { }

/** @type {Outer.Inner} */
var inner;
```
This commit is contained in:
Nathan Shively-Sanders 2017-11-21 10:17:48 -08:00
parent 6c4c10c7cf
commit d2c0ec754b
2 changed files with 13 additions and 2 deletions

View file

@ -1733,13 +1733,24 @@ namespace ts {
return undefined;
}
const right = name.kind === SyntaxKind.QualifiedName ? name.right : name.name;
const namespace = resolveEntityName(left, SymbolFlags.Namespace, ignoreErrors, /*dontResolveAlias*/ false, location);
let namespace = resolveEntityName(left, SymbolFlags.Namespace, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location);
if (!namespace && name.parent && isJSDocTypeReference(name.parent as TypeReferenceType)) {
// jsdoc type references may be values
namespace = resolveEntityName(left, SymbolFlags.Value, ignoreErrors, /*dontResolveAlias*/ false, location);
}
else if (!ignoreErrors) {
// run again for error reporting purposes
resolveEntityName(left, SymbolFlags.Namespace, /*ignoreErrors*/ false, /*dontResolveAlias*/ false, location);
}
if (!namespace || nodeIsMissing(right)) {
return undefined;
}
else if (namespace === unknownSymbol) {
return namespace;
}
if (isInJavaScriptFile(name) && isDeclarationOfFunctionOrClassExpression(namespace)) {
namespace = getSymbolOfNode((namespace.valueDeclaration as VariableDeclaration).initializer);
}
symbol = getSymbol(getExportsOfSymbol(namespace), right.escapedText, meaning);
if (!symbol) {
if (!ignoreErrors) {

View file

@ -1435,7 +1435,7 @@ namespace ts {
}
/**
* Returns true if the node is a variable declaration whose initializer is a function expression.
* Returns true if the node is a variable declaration whose initializer is a function or class expression.
* This function does not test if the node is in a JavaScript file or not.
*/
export function isDeclarationOfFunctionOrClassExpression(s: Symbol) {