From 4b84f56b21b3845cde5b4a0d351e58e684644821 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Fri, 1 Feb 2019 16:09:17 -0800 Subject: [PATCH] Fix type reference dts emit failure --- src/compiler/checker.ts | 17 +++++++++- .../reference/typeReferenceRelatedFiles.js | 34 +++++++++++++++++++ .../typeReferenceRelatedFiles.symbols | 21 ++++++++++++ .../reference/typeReferenceRelatedFiles.types | 21 ++++++++++++ .../typeReferenceRelatedFiles.ts | 18 ++++++++++ 5 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/typeReferenceRelatedFiles.js create mode 100644 tests/baselines/reference/typeReferenceRelatedFiles.symbols create mode 100644 tests/baselines/reference/typeReferenceRelatedFiles.types create mode 100644 tests/cases/conformance/declarationEmit/typeReferenceRelatedFiles.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0cfdeadc00a..875c9b5d185 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -29540,9 +29540,12 @@ namespace ts { return; } const file = host.getSourceFile(resolvedDirective.resolvedFileName)!; - fileToDirective.set(file.path, key); + // Add the transitive closure of path references loaded by this file (as long as they are not) + // part of an existing type reference. + addReferencedFilesToTypeDirective(file, key); }); } + return { getReferencedExportContainer, getReferencedImportDeclaration, @@ -29701,6 +29704,18 @@ namespace ts { } return false; } + + function addReferencedFilesToTypeDirective(file: SourceFile, key: string) { + if (fileToDirective.has(file.path)) return; + fileToDirective.set(file.path, key); + for (const { fileName } of file.referencedFiles) { + const resolvedFile = resolveTripleslashReference(fileName, file.originalFileName); + const referencedFile = host.getSourceFile(resolvedFile); + if (referencedFile) { + addReferencedFilesToTypeDirective(referencedFile, key); + } + } + } } function getExternalModuleFileFromDeclaration(declaration: AnyImportOrReExport | ModuleDeclaration | ImportTypeNode): SourceFile | undefined { diff --git a/tests/baselines/reference/typeReferenceRelatedFiles.js b/tests/baselines/reference/typeReferenceRelatedFiles.js new file mode 100644 index 00000000000..77cf0a8e16d --- /dev/null +++ b/tests/baselines/reference/typeReferenceRelatedFiles.js @@ -0,0 +1,34 @@ +//// [tests/cases/conformance/declarationEmit/typeReferenceRelatedFiles.ts] //// + +//// [index.d.ts] +/// +//// [fs.d.ts] +declare module "fs" { + interface FSWatcher {} +} +//// [package.json] +{ + "name": "@types/node", + "version": "1.0.0" +} +//// [main.ts] +/// +import { FSWatcher } from "fs"; +export function f() { + return {} as FSWatcher; +} + + +//// [main.js] +"use strict"; +exports.__esModule = true; +function f() { + return {}; +} +exports.f = f; + + +//// [main.d.ts] +/// +import { FSWatcher } from "fs"; +export declare function f(): FSWatcher; diff --git a/tests/baselines/reference/typeReferenceRelatedFiles.symbols b/tests/baselines/reference/typeReferenceRelatedFiles.symbols new file mode 100644 index 00000000000..689125fe0fa --- /dev/null +++ b/tests/baselines/reference/typeReferenceRelatedFiles.symbols @@ -0,0 +1,21 @@ +=== tests/cases/conformance/declarationEmit/node_modules/@types/node/index.d.ts === +/// +No type information for this code.=== tests/cases/conformance/declarationEmit/node_modules/@types/node/fs.d.ts === +declare module "fs" { +>"fs" : Symbol("fs", Decl(fs.d.ts, 0, 0)) + + interface FSWatcher {} +>FSWatcher : Symbol(FSWatcher, Decl(fs.d.ts, 0, 21)) +} +=== tests/cases/conformance/declarationEmit/main.ts === +/// +import { FSWatcher } from "fs"; +>FSWatcher : Symbol(FSWatcher, Decl(main.ts, 1, 8)) + +export function f() { +>f : Symbol(f, Decl(main.ts, 1, 31)) + + return {} as FSWatcher; +>FSWatcher : Symbol(FSWatcher, Decl(main.ts, 1, 8)) +} + diff --git a/tests/baselines/reference/typeReferenceRelatedFiles.types b/tests/baselines/reference/typeReferenceRelatedFiles.types new file mode 100644 index 00000000000..824bde2ab98 --- /dev/null +++ b/tests/baselines/reference/typeReferenceRelatedFiles.types @@ -0,0 +1,21 @@ +=== tests/cases/conformance/declarationEmit/node_modules/@types/node/index.d.ts === +/// +No type information for this code.=== tests/cases/conformance/declarationEmit/node_modules/@types/node/fs.d.ts === +declare module "fs" { +>"fs" : typeof import("fs") + + interface FSWatcher {} +} +=== tests/cases/conformance/declarationEmit/main.ts === +/// +import { FSWatcher } from "fs"; +>FSWatcher : any + +export function f() { +>f : () => FSWatcher + + return {} as FSWatcher; +>{} as FSWatcher : FSWatcher +>{} : {} +} + diff --git a/tests/cases/conformance/declarationEmit/typeReferenceRelatedFiles.ts b/tests/cases/conformance/declarationEmit/typeReferenceRelatedFiles.ts new file mode 100644 index 00000000000..f144f15cddb --- /dev/null +++ b/tests/cases/conformance/declarationEmit/typeReferenceRelatedFiles.ts @@ -0,0 +1,18 @@ +// @declaration: true +// @filename: node_modules/@types/node/index.d.ts +/// +// @filename: node_modules/@types/node/fs.d.ts +declare module "fs" { + interface FSWatcher {} +} +// @filename: node_modules/@types/node/package.json +{ + "name": "@types/node", + "version": "1.0.0" +} +// @filename: main.ts +/// +import { FSWatcher } from "fs"; +export function f() { + return {} as FSWatcher; +}