diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index 653832c8dbde7..72526fc4b90c0 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -173,8 +173,7 @@ namespace ts { const compilerOptions = newProgram.getCompilerOptions(); state.compilerOptions = compilerOptions; // With --out or --outFile, any change affects all semantic diagnostics so no need to cache them - // With --isolatedModules, emitting changed file doesnt emit dependent files so we cant know of dependent files to retrieve errors so dont cache the errors - if (!compilerOptions.outFile && !compilerOptions.out && !compilerOptions.isolatedModules) { + if (!compilerOptions.outFile && !compilerOptions.out) { state.semanticDiagnosticsPerFile = createMap(); } state.changedFilesSet = createMap(); @@ -483,16 +482,43 @@ namespace ts { return !state.semanticDiagnosticsFromOldState.size; } + function isChangedSignagure(state: BuilderProgramState, path: Path) { + const newSignature = Debug.assertDefined(state.currentAffectedFilesSignatures).get(path); + const oldSignagure = Debug.assertDefined(state.fileInfos.get(path)).signature; + return newSignature !== oldSignagure; + } + /** * Iterate on referencing modules that export entities from affected file */ function forEachReferencingModulesOfExportOfAffectedFile(state: BuilderProgramState, affectedFile: SourceFile, fn: (state: BuilderProgramState, filePath: Path) => boolean) { // If there was change in signature (dts output) for the changed file, // then only we need to handle pending file emit - if (!state.exportedModulesMap || state.affectedFiles!.length === 1 || !state.changedFilesSet.has(affectedFile.path)) { + if (!state.exportedModulesMap || !state.changedFilesSet.has(affectedFile.path)) { return; } + if (!isChangedSignagure(state, affectedFile.path)) return; + + // Since isolated modules dont change js files, files affected by change in signature is itself + // But we need to cleanup semantic diagnostics and queue dts emit for affected files + if (state.compilerOptions.isolatedModules) { + const seenFileNamesMap = createMap(); + seenFileNamesMap.set(affectedFile.path, true); + const queue = BuilderState.getReferencedByPaths(state, affectedFile.resolvedPath); + while (queue.length > 0) { + const currentPath = queue.pop()!; + if (!seenFileNamesMap.has(currentPath)) { + seenFileNamesMap.set(currentPath, true); + const result = fn(state, currentPath); + if (result && isChangedSignagure(state, currentPath)) { + const currentSourceFile = Debug.assertDefined(state.program).getSourceFileByPath(currentPath)!; + queue.push(...BuilderState.getReferencedByPaths(state, currentSourceFile.resolvedPath)); + } + } + } + } + Debug.assert(!!state.currentAffectedFilesExportedModulesMap); const seenFileAndExportsOfFile = createMap(); // Go through exported modules from cache first diff --git a/src/compiler/builderState.ts b/src/compiler/builderState.ts index 189d801777dc3..b34a0bf837030 100644 --- a/src/compiler/builderState.ts +++ b/src/compiler/builderState.ts @@ -466,7 +466,7 @@ namespace ts.BuilderState { /** * Gets the files referenced by the the file path */ - function getReferencedByPaths(state: Readonly, referencedFilePath: Path) { + export function getReferencedByPaths(state: Readonly, referencedFilePath: Path) { return arrayFrom(mapDefinedIterator(state.referencedMap!.entries(), ([filePath, referencesInFile]) => referencesInFile.has(referencedFilePath) ? filePath as Path : undefined )); diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 275acb64641de..6a8a36dd59007 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2808,10 +2808,6 @@ namespace ts { } if (options.isolatedModules) { - if (getEmitDeclarations(options)) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, getEmitDeclarationOptionName(options), "isolatedModules"); - } - if (options.out) { createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "isolatedModules"); } diff --git a/src/testRunner/unittests/tsbuild/helpers.ts b/src/testRunner/unittests/tsbuild/helpers.ts index e33edf289d381..126b8d2f7d5b2 100644 --- a/src/testRunner/unittests/tsbuild/helpers.ts +++ b/src/testRunner/unittests/tsbuild/helpers.ts @@ -230,7 +230,7 @@ interface Symbol { } } - interface BuildInput { + export interface BuildInput { fs: vfs.FileSystem; tick: () => void; rootNames: readonly string[]; @@ -239,7 +239,7 @@ interface Symbol { baselineBuildInfo?: true; } - function build({ fs, tick, rootNames, modifyFs, baselineSourceMap, baselineBuildInfo }: BuildInput) { + export function tscBuild({ fs, tick, rootNames, modifyFs, baselineSourceMap, baselineBuildInfo }: BuildInput) { const actualReadFileMap = createMap(); modifyFs(fs); tick(); @@ -344,7 +344,7 @@ Mismatch Actual(path, actual, expected): ${JSON.stringify(arrayFrom(mapDefinedIt let host: fakes.SolutionBuilderHost; let initialWrittenFiles: Map; before(() => { - const result = build({ + const result = tscBuild({ fs: projFs().shadow(), tick, rootNames, @@ -390,7 +390,7 @@ Mismatch Actual(path, actual, expected): ${JSON.stringify(arrayFrom(mapDefinedIt tick(); newFs = fs.shadow(); tick(); - ({ actualReadFileMap, host } = build({ + ({ actualReadFileMap, host } = tscBuild({ fs: newFs, tick, rootNames, @@ -429,7 +429,7 @@ Mismatch Actual(path, actual, expected): ${JSON.stringify(arrayFrom(mapDefinedIt }); } it(`Verify emit output file text is same when built clean`, () => { - const { fs, writtenFiles } = build({ + const { fs, writtenFiles } = tscBuild({ fs: newFs.shadow(), tick, rootNames, diff --git a/src/testRunner/unittests/tsbuild/inferredTypeFromTransitiveModule.ts b/src/testRunner/unittests/tsbuild/inferredTypeFromTransitiveModule.ts index 92762dfd49d55..5383b7d32be1a 100644 --- a/src/testRunner/unittests/tsbuild/inferredTypeFromTransitiveModule.ts +++ b/src/testRunner/unittests/tsbuild/inferredTypeFromTransitiveModule.ts @@ -25,7 +25,7 @@ namespace ts { ] }, incrementalDtsChangedBuild: { - modifyFs: fs => replaceText(fs, "/src/bar.ts", "param: string", ""), + modifyFs: changeBarParam, expectedDiagnostics: [ getExpectedDiagnosticForProjectsInBuild("src/tsconfig.json"), [Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, "src/tsconfig.json", "src/obj/bar.js", "src/bar.ts"], @@ -36,5 +36,55 @@ namespace ts { baselineOnly: true, verifyDiagnostics: true }); + + verifyTsbuildOutput({ + scenario: "inferred type from transitive module with isolatedModules", + projFs: () => projFs, + time, + tick, + proj: "inferredTypeFromTransitiveModule", + rootNames: ["/src"], + initialBuild: { modifyFs: changeToIsolatedModules }, + incrementalDtsChangedBuild: { modifyFs: changeBarParam }, + baselineOnly: true, + }); + + it("reports errors in files affected by change in signature", () => { + const { fs, host } = tscBuild({ + fs: projFs.shadow(), + tick, + rootNames: ["/src"], + modifyFs: fs => { + changeToIsolatedModules(fs); + appendText(fs, "/src/lazyIndex.ts", ` +import { default as bar } from './bar'; +bar("hello");`); + } + }); + host.assertErrors(/*empty*/); + + tick(); + const { fs: newFs, host: newHost, writtenFiles } = tscBuild({ + fs: fs.shadow(), + tick, + rootNames: ["/src"], + modifyFs: changeBarParam + }); + // Has errors + newHost.assertErrors({ + message: [Diagnostics.Expected_0_arguments_but_got_1, 0, 1], + location: expectedLocationIndexOf(newFs, "/src/lazyIndex.ts", `"hello"`) + }); + // No written files + assert.equal(writtenFiles.size, 0); + }); }); + + function changeToIsolatedModules(fs: vfs.FileSystem) { + replaceText(fs, "/src/tsconfig.json", `"incremental": true`, `"incremental": true, "isolatedModules": true`); + } + + function changeBarParam(fs: vfs.FileSystem) { + replaceText(fs, "/src/bar.ts", "param: string", ""); + } } diff --git a/src/testRunner/unittests/tscWatch/emitAndErrorUpdates.ts b/src/testRunner/unittests/tscWatch/emitAndErrorUpdates.ts index f41b07b157d8d..908c609e703b6 100644 --- a/src/testRunner/unittests/tscWatch/emitAndErrorUpdates.ts +++ b/src/testRunner/unittests/tscWatch/emitAndErrorUpdates.ts @@ -12,7 +12,8 @@ namespace ts.tscWatch { file, fileStamp: host.getModifiedTime(file.path.replace(".ts", ".js")), errors: builderProgram.getSemanticDiagnostics(watch().getSourceFileByPath(file.path as Path)), - errorsFromOldState: !!state.semanticDiagnosticsFromOldState && state.semanticDiagnosticsFromOldState.has(file.path) + errorsFromOldState: !!state.semanticDiagnosticsFromOldState && state.semanticDiagnosticsFromOldState.has(file.path), + dtsStamp: host.getModifiedTime(file.path.replace(".ts", ".d.ts")) }; } @@ -24,21 +25,36 @@ namespace ts.tscWatch { return find(stampsAndErrors, info => info.file === file)!; } - function verifyOutputFileStampsAndErrors( - file: File, - emitExpected: boolean, - errorRefershExpected: boolean, - beforeChangeFileStampsAndErrors: readonly ReturnType[], - afterChangeFileStampsAndErrors: readonly ReturnType[] - ) { + interface VerifyOutputFileStampAndErrors { + file: File; + jsEmitExpected: boolean; + dtsEmitExpected: boolean; + errorRefershExpected: boolean; + beforeChangeFileStampsAndErrors: readonly ReturnType[]; + afterChangeFileStampsAndErrors: readonly ReturnType[]; + } + function verifyOutputFileStampsAndErrors({ + file, + jsEmitExpected, + dtsEmitExpected, + errorRefershExpected, + beforeChangeFileStampsAndErrors, + afterChangeFileStampsAndErrors + }: VerifyOutputFileStampAndErrors) { const beforeChange = findStampAndErrors(beforeChangeFileStampsAndErrors, file); const afterChange = findStampAndErrors(afterChangeFileStampsAndErrors, file); - if (emitExpected) { + if (jsEmitExpected) { assert.notStrictEqual(afterChange.fileStamp, beforeChange.fileStamp, `Expected emit for file ${file.path}`); } else { assert.strictEqual(afterChange.fileStamp, beforeChange.fileStamp, `Did not expect new emit for file ${file.path}`); } + if (dtsEmitExpected) { + assert.notStrictEqual(afterChange.dtsStamp, beforeChange.dtsStamp, `Expected emit for file ${file.path}`); + } + else { + assert.strictEqual(afterChange.dtsStamp, beforeChange.dtsStamp, `Did not expect new emit for file ${file.path}`); + } if (errorRefershExpected) { if (afterChange.errors !== emptyArray || beforeChange.errors !== emptyArray) { assert.notStrictEqual(afterChange.errors, beforeChange.errors, `Expected new errors for file ${file.path}`); @@ -51,19 +67,22 @@ namespace ts.tscWatch { } } - interface VerifyEmitAndErrorUpdates { - change: (host: WatchedSystem) => void; - getInitialErrors: (watch: Watch) => readonly Diagnostic[] | readonly string[]; - getIncrementalErrors: (watch: Watch) => readonly Diagnostic[] | readonly string[]; - filesWithNewEmit: readonly File[]; - filesWithOnlyErrorRefresh: readonly File[]; - filesNotTouched: readonly File[]; - configFile?: File; + interface VerifyEmitAndErrorUpdatesWorker extends VerifyEmitAndErrorUpdates { + configFile: File; } - - function verifyEmitAndErrorUpdates({ filesWithNewEmit, filesWithOnlyErrorRefresh, filesNotTouched, configFile = config, change, getInitialErrors, getIncrementalErrors }: VerifyEmitAndErrorUpdates) { + function verifyEmitAndErrorUpdatesWorker({ + fileWithChange, + filesWithNewEmit, + filesWithOnlyErrorRefresh, + filesNotTouched, + configFile, + change, + getInitialErrors, + getIncrementalErrors + }: VerifyEmitAndErrorUpdatesWorker) { const nonLibFiles = [...filesWithNewEmit, ...filesWithOnlyErrorRefresh, ...filesNotTouched]; const files = [...nonLibFiles, configFile, libFile]; + const compilerOptions = (JSON.parse(configFile.content).compilerOptions || {}) as CompilerOptions; const host = createWatchedSystem(files, { currentDirectory }); const watch = createWatchOfConfigFile("tsconfig.json", host); checkProgramActualFiles(watch(), [...nonLibFiles.map(f => f.path), libFile.path]); @@ -73,9 +92,77 @@ namespace ts.tscWatch { host.runQueuedTimeoutCallbacks(); checkOutputErrorsIncremental(host, getIncrementalErrors(watch)); const afterChange = getOutputFileStampsAndErrors(host, watch, nonLibFiles); - filesWithNewEmit.forEach(file => verifyOutputFileStampsAndErrors(file, /*emitExpected*/ true, /*errorRefershExpected*/ true, beforeChange, afterChange)); - filesWithOnlyErrorRefresh.forEach(file => verifyOutputFileStampsAndErrors(file, /*emitExpected*/ false, /*errorRefershExpected*/ true, beforeChange, afterChange)); - filesNotTouched.forEach(file => verifyOutputFileStampsAndErrors(file, /*emitExpected*/ false, /*errorRefershExpected*/ false, beforeChange, afterChange)); + filesWithNewEmit.forEach(file => verifyOutputFileStampsAndErrors({ + file, + jsEmitExpected: !compilerOptions.isolatedModules || fileWithChange === file, + dtsEmitExpected: getEmitDeclarations(compilerOptions), + errorRefershExpected: true, + beforeChangeFileStampsAndErrors: beforeChange, + afterChangeFileStampsAndErrors: afterChange + })); + filesWithOnlyErrorRefresh.forEach(file => verifyOutputFileStampsAndErrors({ + file, + jsEmitExpected: false, + dtsEmitExpected: getEmitDeclarations(compilerOptions) && !file.path.endsWith(".d.ts"), + errorRefershExpected: true, + beforeChangeFileStampsAndErrors: beforeChange, + afterChangeFileStampsAndErrors: afterChange + })); + filesNotTouched.forEach(file => verifyOutputFileStampsAndErrors({ + file, + jsEmitExpected: false, + dtsEmitExpected: false, + errorRefershExpected: false, + beforeChangeFileStampsAndErrors: beforeChange, + afterChangeFileStampsAndErrors: afterChange + })); + } + + function changeCompilerOptions(input: VerifyEmitAndErrorUpdates, additionalOptions: CompilerOptions): File { + const configFile = input.configFile || config; + const content = JSON.parse(configFile.content); + content.compilerOptions = { ...content.compilerOptions, ...additionalOptions }; + return { path: configFile.path, content: JSON.stringify(content) }; + } + + interface VerifyEmitAndErrorUpdates { + change: (host: WatchedSystem) => void; + getInitialErrors: (watch: Watch) => readonly Diagnostic[] | readonly string[]; + getIncrementalErrors: (watch: Watch) => readonly Diagnostic[] | readonly string[]; + fileWithChange: File; + filesWithNewEmit: readonly File[]; + filesWithOnlyErrorRefresh: readonly File[]; + filesNotTouched: readonly File[]; + configFile?: File; + } + function verifyEmitAndErrorUpdates(input: VerifyEmitAndErrorUpdates) { + it("with default config", () => { + verifyEmitAndErrorUpdatesWorker({ + ...input, + configFile: input.configFile || config + }); + }); + + it("with default config and --declaration", () => { + verifyEmitAndErrorUpdatesWorker({ + ...input, + configFile: changeCompilerOptions(input, { declaration: true }) + }); + }); + + it("config with --isolatedModules", () => { + verifyEmitAndErrorUpdatesWorker({ + ...input, + configFile: changeCompilerOptions(input, { isolatedModules: true }) + }); + }); + + it("config with --isolatedModules and --declaration", () => { + verifyEmitAndErrorUpdatesWorker({ + ...input, + configFile: changeCompilerOptions(input, { isolatedModules: true, declaration: true }) + }); + }); } describe("deep import changes", () => { @@ -93,6 +180,7 @@ console.log(b.c.d);` addImportedModule(bFile); addImportedModule(cFile); verifyEmitAndErrorUpdates({ + fileWithChange: cFile, filesWithNewEmit, filesWithOnlyErrorRefresh, filesNotTouched: emptyArray, @@ -113,7 +201,7 @@ console.log(b.c.d);` } } - it("updates errors when deep import file changes", () => { + describe("updates errors when deep import file changes", () => { const bFile: File = { path: `${currentDirectory}/b.ts`, content: `import {C} from './c'; @@ -132,7 +220,7 @@ export class B verifyDeepImportChange(bFile, cFile); }); - it("updates errors when deep import through declaration file changes", () => { + describe("updates errors when deep import through declaration file changes", () => { const bFile: File = { path: `${currentDirectory}/b.d.ts`, content: `import {C} from './c'; @@ -152,7 +240,7 @@ export class B }); }); - it("updates errors in file not exporting a deep multilevel import that changes", () => { + describe("updates errors in file not exporting a deep multilevel import that changes", () => { const aFile: File = { path: `${currentDirectory}/a.ts`, content: `export interface Point { @@ -193,6 +281,7 @@ getPoint().c.x;` content: `import "./d";` }; verifyEmitAndErrorUpdates({ + fileWithChange: aFile, filesWithNewEmit: [aFile, bFile], filesWithOnlyErrorRefresh: [cFile, dFile], filesNotTouched: [eFile], @@ -265,6 +354,7 @@ export class Data { filesWithOnlyErrorRefresh.push(lib2Data2); } verifyEmitAndErrorUpdates({ + fileWithChange: lib1ToolsInterface, filesWithNewEmit, filesWithOnlyErrorRefresh, filesNotTouched: emptyArray, @@ -276,11 +366,11 @@ export class Data { ] }); } - it("when there are no circular import and exports", () => { + describe("when there are no circular import and exports", () => { verifyTransitiveExports(lib2Data); }); - it("when there are circular import and exports", () => { + describe("when there are circular import and exports", () => { const lib2Data: File = { path: `${currentDirectory}/lib2/data.ts`, content: `import { ITest } from "lib1/public"; import { Data2 } from "./data2"; diff --git a/tests/baselines/reference/isolatedModulesDeclaration.errors.txt b/tests/baselines/reference/isolatedModulesDeclaration.errors.txt deleted file mode 100644 index 09a655c6da081..0000000000000 --- a/tests/baselines/reference/isolatedModulesDeclaration.errors.txt +++ /dev/null @@ -1,6 +0,0 @@ -error TS5053: Option 'declaration' cannot be specified with option 'isolatedModules'. - - -!!! error TS5053: Option 'declaration' cannot be specified with option 'isolatedModules'. -==== tests/cases/compiler/file1.ts (0 errors) ==== - export var x; \ No newline at end of file diff --git a/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/incremental-declaration-changes/inferred-type-from-transitive-module-with-isolatedModules.js b/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/incremental-declaration-changes/inferred-type-from-transitive-module-with-isolatedModules.js new file mode 100644 index 0000000000000..f8dfdc7e146ca --- /dev/null +++ b/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/incremental-declaration-changes/inferred-type-from-transitive-module-with-isolatedModules.js @@ -0,0 +1,96 @@ +//// [/src/bar.ts] +interface RawAction { + (...args: any[]): Promise | void; +} +interface ActionFactory { + (target: T): T; +} +declare function foo(): ActionFactory; +export default foo()(function foobar(): void { +}); + +//// [/src/obj/bar.d.ts] +declare const _default: () => void; +export default _default; + + +//// [/src/obj/bar.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = foo()(function foobar() { +}); + + +//// [/src/obj/index.d.ts] +import { LazyAction } from './bundling'; +export declare const lazyBar: LazyAction<() => void, typeof import("./lazyIndex")>; + + +//// [/src/obj/lazyIndex.d.ts] file written with same contents +//// [/src/obj/tsconfig.tsbuildinfo] +{ + "program": { + "fileInfos": { + "../../lib/lib.d.ts": { + "version": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", + "signature": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };" + }, + "../bar.ts": { + "version": "747071916-interface RawAction {\r\n (...args: any[]): Promise | void;\r\n}\r\ninterface ActionFactory {\r\n (target: T): T;\r\n}\r\ndeclare function foo(): ActionFactory;\r\nexport default foo()(function foobar(): void {\r\n});", + "signature": "-9232740537-declare const _default: () => void;\r\nexport default _default;\r\n" + }, + "../bundling.ts": { + "version": "-21659820217-export class LazyModule {\r\n constructor(private importCallback: () => Promise) {}\r\n}\r\n\r\nexport class LazyAction<\r\n TAction extends (...args: any[]) => any,\r\n TModule\r\n> {\r\n constructor(_lazyModule: LazyModule, _getter: (module: TModule) => TAction) {\r\n }\r\n}\r\n", + "signature": "-40032907372-export declare class LazyModule {\r\n private importCallback;\r\n constructor(importCallback: () => Promise);\r\n}\r\nexport declare class LazyAction any, TModule> {\r\n constructor(_lazyModule: LazyModule, _getter: (module: TModule) => TAction);\r\n}\r\n" + }, + "../global.d.ts": { + "version": "-9780226215-interface PromiseConstructor {\r\n new (): Promise;\r\n}\r\ndeclare var Promise: PromiseConstructor;\r\ninterface Promise {\r\n}", + "signature": "-9780226215-interface PromiseConstructor {\r\n new (): Promise;\r\n}\r\ndeclare var Promise: PromiseConstructor;\r\ninterface Promise {\r\n}" + }, + "../lazyindex.ts": { + "version": "-6956449754-export { default as bar } from './bar';\n", + "signature": "-6224542381-export { default as bar } from './bar';\r\n" + }, + "../index.ts": { + "version": "-11602502901-import { LazyAction, LazyModule } from './bundling';\r\nconst lazyModule = new LazyModule(() =>\r\n import('./lazyIndex')\r\n);\r\nexport const lazyBar = new LazyAction(lazyModule, m => m.bar);", + "signature": "6256067474-import { LazyAction } from './bundling';\r\nexport declare const lazyBar: LazyAction<() => void, typeof import(\"./lazyIndex\")>;\r\n" + } + }, + "options": { + "target": 1, + "declaration": true, + "outDir": "./", + "incremental": true, + "isolatedModules": true, + "configFilePath": "../tsconfig.json" + }, + "referencedMap": { + "../index.ts": [ + "../bundling.ts", + "../lazyindex.ts" + ], + "../lazyindex.ts": [ + "../bar.ts" + ] + }, + "exportedModulesMap": { + "../index.ts": [ + "../bundling.ts", + "../lazyindex.ts" + ], + "../lazyindex.ts": [ + "../bar.ts" + ] + }, + "semanticDiagnosticsPerFile": [ + "../../lib/lib.d.ts", + "../bar.ts", + "../bundling.ts", + "../global.d.ts", + "../index.ts", + "../lazyindex.ts" + ] + }, + "version": "FakeTSVersion" +} + diff --git a/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/initial-Build/inferred-type-from-transitive-module-with-isolatedModules.js b/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/initial-Build/inferred-type-from-transitive-module-with-isolatedModules.js new file mode 100644 index 0000000000000..568116485a416 --- /dev/null +++ b/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/initial-Build/inferred-type-from-transitive-module-with-isolatedModules.js @@ -0,0 +1,143 @@ +//// [/src/obj/bar.d.ts] +declare const _default: (param: string) => void; +export default _default; + + +//// [/src/obj/bar.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = foo()(function foobar(param) { +}); + + +//// [/src/obj/bundling.d.ts] +export declare class LazyModule { + private importCallback; + constructor(importCallback: () => Promise); +} +export declare class LazyAction any, TModule> { + constructor(_lazyModule: LazyModule, _getter: (module: TModule) => TAction); +} + + +//// [/src/obj/bundling.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LazyModule = /** @class */ (function () { + function LazyModule(importCallback) { + this.importCallback = importCallback; + } + return LazyModule; +}()); +exports.LazyModule = LazyModule; +var LazyAction = /** @class */ (function () { + function LazyAction(_lazyModule, _getter) { + } + return LazyAction; +}()); +exports.LazyAction = LazyAction; + + +//// [/src/obj/index.d.ts] +import { LazyAction } from './bundling'; +export declare const lazyBar: LazyAction<(param: string) => void, typeof import("./lazyIndex")>; + + +//// [/src/obj/index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var bundling_1 = require("./bundling"); +var lazyModule = new bundling_1.LazyModule(function () { + return Promise.resolve().then(function () { return require('./lazyIndex'); }); +}); +exports.lazyBar = new bundling_1.LazyAction(lazyModule, function (m) { return m.bar; }); + + +//// [/src/obj/lazyIndex.d.ts] +export { default as bar } from './bar'; + + +//// [/src/obj/lazyIndex.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var bar_1 = require("./bar"); +exports.bar = bar_1.default; + + +//// [/src/obj/tsconfig.tsbuildinfo] +{ + "program": { + "fileInfos": { + "../../lib/lib.d.ts": { + "version": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", + "signature": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };" + }, + "../bar.ts": { + "version": "5936740878-interface RawAction {\r\n (...args: any[]): Promise | void;\r\n}\r\ninterface ActionFactory {\r\n (target: T): T;\r\n}\r\ndeclare function foo(): ActionFactory;\r\nexport default foo()(function foobar(param: string): void {\r\n});", + "signature": "11191036521-declare const _default: (param: string) => void;\r\nexport default _default;\r\n" + }, + "../bundling.ts": { + "version": "-21659820217-export class LazyModule {\r\n constructor(private importCallback: () => Promise) {}\r\n}\r\n\r\nexport class LazyAction<\r\n TAction extends (...args: any[]) => any,\r\n TModule\r\n> {\r\n constructor(_lazyModule: LazyModule, _getter: (module: TModule) => TAction) {\r\n }\r\n}\r\n", + "signature": "-40032907372-export declare class LazyModule {\r\n private importCallback;\r\n constructor(importCallback: () => Promise);\r\n}\r\nexport declare class LazyAction any, TModule> {\r\n constructor(_lazyModule: LazyModule, _getter: (module: TModule) => TAction);\r\n}\r\n" + }, + "../global.d.ts": { + "version": "-9780226215-interface PromiseConstructor {\r\n new (): Promise;\r\n}\r\ndeclare var Promise: PromiseConstructor;\r\ninterface Promise {\r\n}", + "signature": "-9780226215-interface PromiseConstructor {\r\n new (): Promise;\r\n}\r\ndeclare var Promise: PromiseConstructor;\r\ninterface Promise {\r\n}" + }, + "../lazyindex.ts": { + "version": "-6956449754-export { default as bar } from './bar';\n", + "signature": "-6224542381-export { default as bar } from './bar';\r\n" + }, + "../index.ts": { + "version": "-11602502901-import { LazyAction, LazyModule } from './bundling';\r\nconst lazyModule = new LazyModule(() =>\r\n import('./lazyIndex')\r\n);\r\nexport const lazyBar = new LazyAction(lazyModule, m => m.bar);", + "signature": "18468008756-import { LazyAction } from './bundling';\r\nexport declare const lazyBar: LazyAction<(param: string) => void, typeof import(\"./lazyIndex\")>;\r\n" + } + }, + "options": { + "target": 1, + "declaration": true, + "outDir": "./", + "incremental": true, + "isolatedModules": true, + "configFilePath": "../tsconfig.json" + }, + "referencedMap": { + "../index.ts": [ + "../bundling.ts", + "../lazyindex.ts" + ], + "../lazyindex.ts": [ + "../bar.ts" + ] + }, + "exportedModulesMap": { + "../index.ts": [ + "../bundling.ts", + "../lazyindex.ts" + ], + "../lazyindex.ts": [ + "../bar.ts" + ] + }, + "semanticDiagnosticsPerFile": [ + "../../lib/lib.d.ts", + "../bar.ts", + "../bundling.ts", + "../global.d.ts", + "../index.ts", + "../lazyindex.ts" + ] + }, + "version": "FakeTSVersion" +} + +//// [/src/tsconfig.json] +{ + "compilerOptions": { + "target": "es5", + "declaration": true, + "outDir": "obj", + "incremental": true, "isolatedModules": true + } +} +