@@ -390,6 +390,88 @@ func TestBuildFileDelete(t *testing.T) {
390390 }
391391}
392392
393+ func TestBuildInferredTypeFromTransitiveModule (t * testing.T ) {
394+ t .Parallel ()
395+ testCases := []* tscInput {
396+ {
397+ subScenario : "inferred type from transitive module" ,
398+ files : getBuildInferredTypeFromTransitiveModuleMap (false , "" ),
399+ commandLineArgs : []string {"--b" , "--verbose" },
400+ edits : []* tscEdit {
401+ {
402+ caption : "incremental-declaration-changes" ,
403+ edit : func (sys * testSys ) {
404+ sys .replaceFileText ("/home/src/workspaces/project/bar.ts" , "param: string" , "" )
405+ },
406+ },
407+ {
408+ caption : "incremental-declaration-changes" ,
409+ edit : func (sys * testSys ) {
410+ sys .replaceFileText ("/home/src/workspaces/project/bar.ts" , "foobar()" , "foobar(param: string)" )
411+ },
412+ },
413+ },
414+ },
415+ {
416+ subScenario : "inferred type from transitive module with isolatedModules" ,
417+ files : getBuildInferredTypeFromTransitiveModuleMap (true , "" ),
418+ commandLineArgs : []string {"--b" , "--verbose" },
419+ edits : []* tscEdit {
420+ {
421+ caption : "incremental-declaration-changes" ,
422+ edit : func (sys * testSys ) {
423+ sys .replaceFileText ("/home/src/workspaces/project/bar.ts" , "param: string" , "" )
424+ },
425+ },
426+ {
427+ caption : "incremental-declaration-changes" ,
428+ edit : func (sys * testSys ) {
429+ sys .replaceFileText ("/home/src/workspaces/project/bar.ts" , "foobar()" , "foobar(param: string)" )
430+ },
431+ },
432+ },
433+ },
434+ {
435+ subScenario : "reports errors in files affected by change in signature with isolatedModules" ,
436+ files : getBuildInferredTypeFromTransitiveModuleMap (true , stringtestutil .Dedent (`
437+ import { default as bar } from './bar';
438+ bar("hello");
439+ ` )),
440+ commandLineArgs : []string {"--b" , "--verbose" },
441+ edits : []* tscEdit {
442+ {
443+ caption : "incremental-declaration-changes" ,
444+ edit : func (sys * testSys ) {
445+ sys .replaceFileText ("/home/src/workspaces/project/bar.ts" , "param: string" , "" )
446+ },
447+ },
448+ {
449+ caption : "incremental-declaration-changes" ,
450+ edit : func (sys * testSys ) {
451+ sys .replaceFileText ("/home/src/workspaces/project/bar.ts" , "foobar()" , "foobar(param: string)" )
452+ },
453+ },
454+ {
455+ caption : "incremental-declaration-changes" ,
456+ edit : func (sys * testSys ) {
457+ sys .replaceFileText ("/home/src/workspaces/project/bar.ts" , "param: string" , "" )
458+ },
459+ },
460+ {
461+ caption : "Fix Error" ,
462+ edit : func (sys * testSys ) {
463+ sys .replaceFileText ("/home/src/workspaces/project/lazyIndex.ts" , `bar("hello")` , "bar()" )
464+ },
465+ },
466+ },
467+ },
468+ }
469+
470+ for _ , test := range testCases {
471+ test .run (t , "inferredTypeFromTransitiveModule" )
472+ }
473+ }
474+
393475func TestBuildSolutionProject (t * testing.T ) {
394476 t .Parallel ()
395477 testCases := []* tscInput {
@@ -756,3 +838,60 @@ func getBuildEmitDeclarationOnlyTestCase(declarationMap bool) *tscInput {
756838 },
757839 }
758840}
841+
842+ func getBuildInferredTypeFromTransitiveModuleMap (isolatedModules bool , lazyExtraContents string ) FileMap {
843+ return FileMap {
844+ "/home/src/workspaces/project/bar.ts" : stringtestutil .Dedent (`
845+ interface RawAction {
846+ (...args: any[]): Promise<any> | void;
847+ }
848+ interface ActionFactory {
849+ <T extends RawAction>(target: T): T;
850+ }
851+ declare function foo<U extends any[] = any[]>(): ActionFactory;
852+ export default foo()(function foobar(param: string): void {
853+ });
854+ ` ),
855+ "/home/src/workspaces/project/bundling.ts" : stringtestutil .Dedent (`
856+ export class LazyModule<TModule> {
857+ constructor(private importCallback: () => Promise<TModule>) {}
858+ }
859+
860+ export class LazyAction<
861+ TAction extends (...args: any[]) => any,
862+ TModule
863+ > {
864+ constructor(_lazyModule: LazyModule<TModule>, _getter: (module: TModule) => TAction) {
865+ }
866+ }
867+ ` ),
868+ "/home/src/workspaces/project/global.d.ts" : stringtestutil .Dedent (`
869+ interface PromiseConstructor {
870+ new <T>(): Promise<T>;
871+ }
872+ declare var Promise: PromiseConstructor;
873+ interface Promise<T> {
874+ }
875+ ` ),
876+ "/home/src/workspaces/project/index.ts" : stringtestutil .Dedent (`
877+ import { LazyAction, LazyModule } from './bundling';
878+ const lazyModule = new LazyModule(() =>
879+ import('./lazyIndex')
880+ );
881+ export const lazyBar = new LazyAction(lazyModule, m => m.bar);
882+ ` ),
883+ "/home/src/workspaces/project/lazyIndex.ts" : stringtestutil .Dedent (`
884+ export { default as bar } from './bar';
885+ ` ) + lazyExtraContents ,
886+ "/home/src/workspaces/project/tsconfig.json" : stringtestutil .Dedent (fmt .Sprintf (`
887+ {
888+ "compilerOptions": {
889+ "target": "es5",
890+ "declaration": true,
891+ "outDir": "obj",
892+ "incremental": true,
893+ "isolatedModules": %t,
894+ },
895+ }` , isolatedModules )),
896+ }
897+ }
0 commit comments