diff --git a/tsc/internal/execute/incremental/programtosnapshot.go b/tsc/internal/execute/incremental/programtosnapshot.go index 14f7b99fc1815..6b7d558cf971d 100644 --- a/tsc/internal/execute/incremental/programtosnapshot.go +++ b/tsc/internal/execute/incremental/programtosnapshot.go @@ -260,6 +260,10 @@ func (t *toProgramSnapshot) handlePendingCheck() { func fileAffectsGlobalScope(file *ast.SourceFile) bool { binder.BindSourceFile(file) + // UMD exports introduce global names even though the file is an external module. + if len(file.GlobalExports) > 0 { + return true + } // if file contains anything that augments to global scope we need to build them as if // they are global files as well as module if core.Some(file.ModuleAugmentations, func(augmentation *ast.ModuleName) bool { diff --git a/tsc/internal/execute/tsctests/umd_test.go b/tsc/internal/execute/tsctests/umd_test.go new file mode 100644 index 0000000000000..1c8252c142fc6 --- /dev/null +++ b/tsc/internal/execute/tsctests/umd_test.go @@ -0,0 +1,72 @@ +package tsctests + +import "testing" + +func TestTscUMD(t *testing.T) { + t.Parallel() + for _, args := range [][]string{nil, {"--watch"}} { + const umdPath = "/home/src/workspaces/project/umd.d.ts" + const present = "export as namespace UmdApi;\nexport interface Item { value: number }\n" + (&tscInput{ + subScenario: "UMD global export changes invalidate unchanged consumers", + commandLineArgs: args, + files: FileMap{ + "/home/src/workspaces/project/tsconfig.json": `{"compilerOptions":{"strict":true,"incremental":true,"noEmit":true,"types":[]},"include":["*.ts"]}`, + umdPath: present, + "/home/src/workspaces/project/client.ts": "declare const item: UmdApi.Item;\nconst checked: number = item.value;\n", + }, + edits: []*tscEdit{ + noChange, + { + caption: "remove the global namespace export", + edit: func(sys *TestSys) { + sys.writeFileNoError(umdPath, "export interface Item { value: number }\n") + }, + }, + { + caption: "restore the global namespace export", + edit: func(sys *TestSys) { + sys.writeFileNoError(umdPath, present) + }, + }, + { + caption: "rename the global namespace export", + edit: func(sys *TestSys) { + sys.replaceFileText(umdPath, "UmdApi", "OtherApi") + }, + }, + { + caption: "restore the global namespace name", + edit: func(sys *TestSys) { + sys.writeFileNoError(umdPath, present) + }, + }, + { + caption: "make the exported property incompatible", + edit: func(sys *TestSys) { + sys.replaceFileText(umdPath, "value: number", "value: string") + }, + }, + { + caption: "restore the exported property type", + edit: func(sys *TestSys) { + sys.writeFileNoError(umdPath, present) + }, + }, + { + caption: "delete the UMD declaration file", + edit: func(sys *TestSys) { + sys.removeNoError(umdPath) + }, + }, + { + caption: "restore the UMD declaration file", + edit: func(sys *TestSys) { + sys.writeFileNoError(umdPath, present) + }, + }, + noChange, + }, + }).run(t, "umd") + } +}