diff --git a/src/testRunner/tsconfig.json b/src/testRunner/tsconfig.json index d3ea4744e8a..52131bd6c28 100644 --- a/src/testRunner/tsconfig.json +++ b/src/testRunner/tsconfig.json @@ -92,6 +92,7 @@ "unittests/tsbuild/amdModulesWithOut.ts", "unittests/tsbuild/emptyFiles.ts", "unittests/tsbuild/graphOrdering.ts", + "unittests/tsbuild//inferredTypeFromTransitiveModule.ts", "unittests/tsbuild/missingExtendedFile.ts", "unittests/tsbuild/outFile.ts", "unittests/tsbuild/referencesWithRootDirInParent.ts", diff --git a/src/testRunner/unittests/tsbuild/helpers.ts b/src/testRunner/unittests/tsbuild/helpers.ts index 6915dd5d3b7..538ebd75cdb 100644 --- a/src/testRunner/unittests/tsbuild/helpers.ts +++ b/src/testRunner/unittests/tsbuild/helpers.ts @@ -305,7 +305,7 @@ Mismatch Actual(path, actual, expected): ${JSON.stringify(arrayFrom(mapDefinedIt actualReadFileMap = undefined!; host = undefined!; }); - if (!baselineOnly) { + if (!baselineOnly || verifyDiagnostics) { it(`verify diagnostics`, () => { host.assertDiagnosticMessages(...(incrementalExpectedDiagnostics || emptyArray)); }); diff --git a/src/testRunner/unittests/tsbuild/inferredTypeFromTransitiveModule.ts b/src/testRunner/unittests/tsbuild/inferredTypeFromTransitiveModule.ts new file mode 100644 index 00000000000..792fefb7ba7 --- /dev/null +++ b/src/testRunner/unittests/tsbuild/inferredTypeFromTransitiveModule.ts @@ -0,0 +1,49 @@ +namespace ts { + describe("unittests:: tsbuild:: inferredTypeFromTransitiveModule::", () => { + let projFs: vfs.FileSystem; + const { time, tick } = getTime(); + before(() => { + projFs = loadProjectFromDisk("tests/projects/inferredTypeFromTransitiveModule", time); + }); + after(() => { + projFs = undefined!; + }); + + verifyTsbuildOutput({ + scenario: "inferred type from transitive module", + projFs: () => projFs, + time, + tick, + proj: "inferredTypeFromTransitiveModule", + rootNames: ["/src"], + expectedMapFileNames: emptyArray, + lastProjectOutputJs: `/src/obj/index.js`, + outputFiles: [ + "/src/obj/bar.js", "/src/obj/bar.d.ts", + "/src/obj/bundling.js", "/src/obj/bundling.d.ts", + "/src/obj/lazyIndex.js", "/src/obj/lazyIndex.d.ts", + "/src/obj/index.js", "/src/obj/index.d.ts", + "/src/obj/tsconfig.tsbuildinfo" + ], + initialBuild: { + modifyFs: noop, + expectedDiagnostics: [ + getExpectedDiagnosticForProjectsInBuild("src/tsconfig.json"), + [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/tsconfig.json", "src/obj/bar.js"], + [Diagnostics.Building_project_0, "/src/tsconfig.json"] + ] + }, + incrementalDtsChangedBuild: { + modifyFs: fs => replaceText(fs, "/src/bar.ts", "param: string", ""), + 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"], + [Diagnostics.Building_project_0, "/src/tsconfig.json"], + [Diagnostics.Updating_unchanged_output_timestamps_of_project_0, "/src/tsconfig.json"] + ] + }, + baselineOnly: true, + verifyDiagnostics: true + }); + }); +} diff --git a/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/incremental-declaration-changes/inferred-type-from-transitive-module.js b/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/incremental-declaration-changes/inferred-type-from-transitive-module.js new file mode 100644 index 00000000000..ea6e9ff01c6 --- /dev/null +++ b/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/incremental-declaration-changes/inferred-type-from-transitive-module.js @@ -0,0 +1,93 @@ +//// [/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/tsconfig.tsbuildinfo] +{ + "program": { + "fileInfos": { + "/lib/lib.es5.d.ts": { + "version": "/lib/lib.es5.d.ts", + "signature": "/lib/lib.es5.d.ts" + }, + "/lib/lib.es2015.promise.d.ts": { + "version": "/lib/lib.es2015.promise.d.ts", + "signature": "/lib/lib.es2015.promise.d.ts" + }, + "/src/bar.ts": { + "version": "747071916", + "signature": "-9232740537" + }, + "/src/bundling.ts": { + "version": "-21659820217", + "signature": "-40032907372" + }, + "/src/lazyindex.ts": { + "version": "-6956449754", + "signature": "-6224542381" + }, + "/src/index.ts": { + "version": "-11602502901", + "signature": "18468008756" + } + }, + "options": { + "target": 1, + "declaration": true, + "outDir": "/src/obj", + "incremental": true, + "lib": [ + "lib.es5.d.ts", + "lib.es2015.promise.d.ts" + ], + "configFilePath": "/src/tsconfig.json" + }, + "referencedMap": { + "/src/index.ts": [ + "/src/bundling.ts", + "/src/lazyindex.ts" + ], + "/src/lazyindex.ts": [ + "/src/bar.ts" + ] + }, + "exportedModulesMap": { + "/src/index.ts": [ + "/src/bundling.ts", + "/src/lazyindex.ts" + ], + "/src/lazyindex.ts": [ + "/src/bar.ts" + ] + }, + "semanticDiagnosticsPerFile": [ + "/lib/lib.es2015.promise.d.ts", + "/lib/lib.es5.d.ts", + "/src/bar.ts", + "/src/bundling.ts", + "/src/index.ts", + "/src/lazyindex.ts" + ] + }, + "version": "FakeTSVersion" +} + diff --git a/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/initial-Build/inferred-type-from-transitive-module.js b/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/initial-Build/inferred-type-from-transitive-module.js new file mode 100644 index 00000000000..d18a805edf4 --- /dev/null +++ b/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/initial-Build/inferred-type-from-transitive-module.js @@ -0,0 +1,136 @@ +//// [/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.es5.d.ts": { + "version": "/lib/lib.es5.d.ts", + "signature": "/lib/lib.es5.d.ts" + }, + "/lib/lib.es2015.promise.d.ts": { + "version": "/lib/lib.es2015.promise.d.ts", + "signature": "/lib/lib.es2015.promise.d.ts" + }, + "/src/bar.ts": { + "version": "5936740878", + "signature": "11191036521" + }, + "/src/bundling.ts": { + "version": "-21659820217", + "signature": "-40032907372" + }, + "/src/lazyindex.ts": { + "version": "-6956449754", + "signature": "-6224542381" + }, + "/src/index.ts": { + "version": "-11602502901", + "signature": "18468008756" + } + }, + "options": { + "target": 1, + "declaration": true, + "outDir": "/src/obj", + "incremental": true, + "lib": [ + "lib.es5.d.ts", + "lib.es2015.promise.d.ts" + ], + "configFilePath": "/src/tsconfig.json" + }, + "referencedMap": { + "/src/index.ts": [ + "/src/bundling.ts", + "/src/lazyindex.ts" + ], + "/src/lazyindex.ts": [ + "/src/bar.ts" + ] + }, + "exportedModulesMap": { + "/src/index.ts": [ + "/src/bundling.ts", + "/src/lazyindex.ts" + ], + "/src/lazyindex.ts": [ + "/src/bar.ts" + ] + }, + "semanticDiagnosticsPerFile": [ + "/lib/lib.es2015.promise.d.ts", + "/lib/lib.es5.d.ts", + "/src/bar.ts", + "/src/bundling.ts", + "/src/index.ts", + "/src/lazyindex.ts" + ] + }, + "version": "FakeTSVersion" +} + diff --git a/tests/projects/inferredTypeFromTransitiveModule/bar.ts b/tests/projects/inferredTypeFromTransitiveModule/bar.ts new file mode 100644 index 00000000000..84efa817b01 --- /dev/null +++ b/tests/projects/inferredTypeFromTransitiveModule/bar.ts @@ -0,0 +1,9 @@ +interface RawAction { + (...args: any[]): Promise | void; +} +interface ActionFactory { + (target: T): T; +} +declare function foo(): ActionFactory; +export default foo()(function foobar(param: string): void { +}); \ No newline at end of file diff --git a/tests/projects/inferredTypeFromTransitiveModule/bundling.ts b/tests/projects/inferredTypeFromTransitiveModule/bundling.ts new file mode 100644 index 00000000000..dc7fd0d1864 --- /dev/null +++ b/tests/projects/inferredTypeFromTransitiveModule/bundling.ts @@ -0,0 +1,11 @@ +export class LazyModule { + constructor(private importCallback: () => Promise) {} +} + +export class LazyAction< + TAction extends (...args: any[]) => any, + TModule +> { + constructor(_lazyModule: LazyModule, _getter: (module: TModule) => TAction) { + } +} diff --git a/tests/projects/inferredTypeFromTransitiveModule/index.ts b/tests/projects/inferredTypeFromTransitiveModule/index.ts new file mode 100644 index 00000000000..f5adaa5eb2a --- /dev/null +++ b/tests/projects/inferredTypeFromTransitiveModule/index.ts @@ -0,0 +1,5 @@ +import { LazyAction, LazyModule } from './bundling'; +const lazyModule = new LazyModule(() => + import('./lazyIndex') +); +export const lazyBar = new LazyAction(lazyModule, m => m.bar); \ No newline at end of file diff --git a/tests/projects/inferredTypeFromTransitiveModule/lazyIndex.ts b/tests/projects/inferredTypeFromTransitiveModule/lazyIndex.ts new file mode 100644 index 00000000000..1b1a7743ed7 --- /dev/null +++ b/tests/projects/inferredTypeFromTransitiveModule/lazyIndex.ts @@ -0,0 +1 @@ +export { default as bar } from './bar'; diff --git a/tests/projects/inferredTypeFromTransitiveModule/tsconfig.json b/tests/projects/inferredTypeFromTransitiveModule/tsconfig.json new file mode 100644 index 00000000000..4663dd37883 --- /dev/null +++ b/tests/projects/inferredTypeFromTransitiveModule/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "target": "es5", + "declaration": true, + "outDir": "obj", + "incremental": true, + "lib": ["es5", "es2015.promise"] + } +} \ No newline at end of file