diff --git a/packages/compiler-cli/src/ngtsc/metadata/src/resolver.ts b/packages/compiler-cli/src/ngtsc/metadata/src/resolver.ts index cb89986276..fdb48b9eb9 100644 --- a/packages/compiler-cli/src/ngtsc/metadata/src/resolver.ts +++ b/packages/compiler-cli/src/ngtsc/metadata/src/resolver.ts @@ -439,10 +439,7 @@ class StaticInterpreter { if (this.host.isClass(node)) { return this.getReference(node, context); } else if (ts.isVariableDeclaration(node)) { - if (!node.initializer) { - return undefined; - } - return this.visitExpression(node.initializer, context); + return this.visitVariableDeclaration(node, context); } else if (ts.isParameter(node) && context.scope.has(node)) { return context.scope.get(node) !; } else if (ts.isExportAssignment(node)) { @@ -456,6 +453,16 @@ class StaticInterpreter { } } + private visitVariableDeclaration(node: ts.VariableDeclaration, context: Context): ResolvedValue { + if (node.initializer !== undefined) { + return this.visitExpression(node.initializer, context); + } else if (isVariableDeclarationDeclared(node)) { + return this.getReference(node, context); + } else { + return undefined; + } + } + private visitEnumDeclaration(node: ts.EnumDeclaration, context: Context): ResolvedValue { const enumRef = this.getReference(node, context) as Reference; const map = new Map(); @@ -728,3 +735,16 @@ function identifierOfDeclaration(decl: ts.Declaration): ts.Identifier|undefined function isPossibleClassDeclaration(node: ts.Node): node is ts.Declaration { return ts.isClassDeclaration(node) || ts.isVariableDeclaration(node); } + +function isVariableDeclarationDeclared(node: ts.VariableDeclaration): boolean { + if (node.parent === undefined || !ts.isVariableDeclarationList(node.parent)) { + return false; + } + const declList = node.parent; + if (declList.parent === undefined || !ts.isVariableStatement(declList.parent)) { + return false; + } + const varStmt = declList.parent; + return varStmt.modifiers !== undefined && + varStmt.modifiers.some(mod => mod.kind === ts.SyntaxKind.DeclareKeyword); +} diff --git a/packages/compiler-cli/src/ngtsc/metadata/test/resolver_spec.ts b/packages/compiler-cli/src/ngtsc/metadata/test/resolver_spec.ts index 7c4863a6dd..f25f517fc7 100644 --- a/packages/compiler-cli/src/ngtsc/metadata/test/resolver_spec.ts +++ b/packages/compiler-cli/src/ngtsc/metadata/test/resolver_spec.ts @@ -284,4 +284,17 @@ describe('ngtsc metadata', () => { expect(result.enumRef.node.name.text).toBe('Foo'); expect(result.name).toBe('B'); }); + + it('variable declaration resolution works', () => { + const {program} = makeProgram([ + {name: 'decl.d.ts', contents: 'export declare let value: number;'}, + {name: 'entry.ts', contents: `import {value} from './decl'; const target$ = value;`}, + ]); + const checker = program.getTypeChecker(); + const host = new TypeScriptReflectionHost(checker); + const result = getDeclaration(program, 'entry.ts', 'target$', ts.isVariableDeclaration); + const res = staticallyResolve(result.initializer !, host, checker); + console.error(res); + expect(res instanceof Reference).toBe(true); + }); });