diff --git a/internal/compiler/program.go b/internal/compiler/program.go
index 35093fab681..a4bc6fca222 100644
--- a/internal/compiler/program.go
+++ b/internal/compiler/program.go
@@ -1631,6 +1631,11 @@ func (p *Program) Emit(ctx context.Context, options EmitOptions) *EmitResult {
}
if options.EmitOnly != EmitOnlyForcedDts {
+ if p.Options().NoEmit.IsTrue() {
+ // Mirror handleNoEmitOptions: a single-file noEmit is skipped, but a whole-program
+ // noEmit is not, so a program with diagnostics reports DiagnosticsPresent_OutputsGenerated.
+ return &EmitResult{EmitSkipped: options.TargetSourceFile != nil}
+ }
result := HandleNoEmitOnError(
ctx,
p,
diff --git a/internal/execute/tsctests/tsc_test.go b/internal/execute/tsctests/tsc_test.go
index 46128bbb759..693184fcce0 100644
--- a/internal/execute/tsctests/tsc_test.go
+++ b/internal/execute/tsctests/tsc_test.go
@@ -118,6 +118,11 @@ func TestTscCommandline(t *testing.T) {
files: FileMap{"/home/src/workspaces/project/first.ts": `export const Key = Symbol()`},
commandLineArgs: []string{"--lib", "es6 ", "first.ts"},
},
+ {
+ subScenario: "noEmit with type error",
+ files: FileMap{"/home/src/workspaces/project/index.ts": `x = 5;`},
+ commandLineArgs: []string{"--noEmit", "index.ts"},
+ },
{
subScenario: "option diagnostics are suppressed when there are syntactic errors",
files: FileMap{"/home/src/workspaces/project/a.ts": `const x: = 1;`},
diff --git a/testdata/baselines/reference/tsc/commandLine/noEmit-with-type-error.js b/testdata/baselines/reference/tsc/commandLine/noEmit-with-type-error.js
new file mode 100644
index 00000000000..fbe6848a262
--- /dev/null
+++ b/testdata/baselines/reference/tsc/commandLine/noEmit-with-type-error.js
@@ -0,0 +1,41 @@
+currentDirectory::/home/src/workspaces/project
+useCaseSensitiveFileNames::true
+Input::
+//// [/home/src/workspaces/project/index.ts] *new*
+x = 5;
+
+tsgo --noEmit index.ts
+ExitStatus:: DiagnosticsPresent_OutputsGenerated
+Output::
+[96mindex.ts[0m:[93m1[0m:[93m1[0m - [91merror[0m[90m TS2304: [0mCannot find name 'x'.
+
+[7m1[0m x = 5;
+[7m [0m [91m~[0m
+
+
+Found 1 error in index.ts[90m:1[0m
+
+//// [/home/src/tslibs/TS/Lib/lib.es2025.full.d.ts] *Lib*
+///
+interface Boolean {}
+interface Function {}
+interface CallableFunction {}
+interface NewableFunction {}
+interface IArguments {}
+interface Number { toExponential: any; }
+interface Object {}
+interface RegExp {}
+interface String { charAt: any; }
+interface Array { length: number; [n: number]: T; }
+interface ReadonlyArray {}
+interface SymbolConstructor {
+ (desc?: string | number): symbol;
+ for(name: string): symbol;
+ readonly toStringTag: symbol;
+}
+declare var Symbol: SymbolConstructor;
+interface Symbol {
+ readonly [Symbol.toStringTag]: string;
+}
+declare const console: { log(msg: any): void; };
+
diff --git a/testdata/baselines/reference/tsc/generateTrace/generateTrace-generates-types-file.js b/testdata/baselines/reference/tsc/generateTrace/generateTrace-generates-types-file.js
index 7905bb21b6b..ac1c0aa7a47 100644
--- a/testdata/baselines/reference/tsc/generateTrace/generateTrace-generates-types-file.js
+++ b/testdata/baselines/reference/tsc/generateTrace/generateTrace-generates-types-file.js
@@ -77,9 +77,7 @@ declare const console: { log(msg: any): void; };
{"pid":1,"tid":2,"ph":"E","cat":"check","ts":18,"name":"checkSourceFile","args":{"checkerId":0,"path":"/home/src/workspaces/project/a.ts"}},
{"pid":1,"tid":1,"ph":"E","cat":"check","ts":19,"name":"checkSourceFiles"},
{"pid":1,"tid":1,"ph":"B","cat":"emit","ts":20,"name":"emit"},
-{"pid":1,"tid":354130385,"ph":"B","cat":"emit","ts":21,"name":"emit","args":{"path":"/home/src/workspaces/project/a.ts"}},
-{"pid":1,"tid":354130385,"ph":"E","cat":"emit","ts":22,"name":"emit","args":{"path":"/home/src/workspaces/project/a.ts"}},
-{"pid":1,"tid":1,"ph":"E","cat":"emit","ts":23,"name":"emit"}
+{"pid":1,"tid":1,"ph":"E","cat":"emit","ts":21,"name":"emit"}
]
//// [/home/src/workspaces/project/trace/types_0.json] *new*
diff --git a/testdata/baselines/reference/tsc/generateTrace/generateTrace-with-multiple-files-and-complex-types.js b/testdata/baselines/reference/tsc/generateTrace/generateTrace-with-multiple-files-and-complex-types.js
index d981e92cb2f..befa8be5368 100644
--- a/testdata/baselines/reference/tsc/generateTrace/generateTrace-with-multiple-files-and-complex-types.js
+++ b/testdata/baselines/reference/tsc/generateTrace/generateTrace-with-multiple-files-and-complex-types.js
@@ -20,7 +20,7 @@ export interface Container {
export type Nullable = T | null | undefined;
tsgo --generateTrace /home/src/workspaces/project/trace --singleThreaded
-ExitStatus:: DiagnosticsPresent_OutputsSkipped
+ExitStatus:: DiagnosticsPresent_OutputsGenerated
Output::
[96mmain.ts[0m:[93m2[0m:[93m74[0m - [91merror[0m[90m TS2322: [0mType '(fn: (x: number) => U) => Container' is not assignable to type '(fn: (x: U) => U) => Container'.
Types of parameters 'fn' and 'fn' are incompatible.
@@ -104,11 +104,7 @@ declare const console: { log(msg: any): void; };
{"pid":1,"tid":2,"ph":"E","cat":"check","ts":24,"name":"checkSourceFile","args":{"checkerId":0,"path":"/home/src/workspaces/project/main.ts"}},
{"pid":1,"tid":1,"ph":"E","cat":"check","ts":25,"name":"checkSourceFiles"},
{"pid":1,"tid":1,"ph":"B","cat":"emit","ts":26,"name":"emit"},
-{"pid":1,"tid":100209852,"ph":"B","cat":"emit","ts":27,"name":"emit","args":{"path":"/home/src/workspaces/project/main.ts"}},
-{"pid":1,"tid":100209852,"ph":"E","cat":"emit","ts":28,"name":"emit","args":{"path":"/home/src/workspaces/project/main.ts"}},
-{"pid":1,"tid":553096334,"ph":"B","cat":"emit","ts":29,"name":"emit","args":{"path":"/home/src/workspaces/project/types.ts"}},
-{"pid":1,"tid":553096334,"ph":"E","cat":"emit","ts":30,"name":"emit","args":{"path":"/home/src/workspaces/project/types.ts"}},
-{"pid":1,"tid":1,"ph":"E","cat":"emit","ts":31,"name":"emit"}
+{"pid":1,"tid":1,"ph":"E","cat":"emit","ts":27,"name":"emit"}
]
//// [/home/src/workspaces/project/trace/types_0.json] *new*
diff --git a/testdata/baselines/reference/tsc/noEmit/dts-errors.js b/testdata/baselines/reference/tsc/noEmit/dts-errors.js
index 67254f6a2b2..299fdcb8dac 100644
--- a/testdata/baselines/reference/tsc/noEmit/dts-errors.js
+++ b/testdata/baselines/reference/tsc/noEmit/dts-errors.js
@@ -12,7 +12,7 @@ const a = class { private p = 10; };
}
tsgo --noEmit
-ExitStatus:: DiagnosticsPresent_OutputsSkipped
+ExitStatus:: DiagnosticsPresent_OutputsGenerated
Output::
[96ma.ts[0m:[93m1[0m:[93m7[0m - [91merror[0m[90m TS4094: [0mProperty 'p' of exported anonymous class type may not be private or protected.
@@ -55,7 +55,7 @@ declare const console: { log(msg: any): void; };
Edit [0]:: no change
tsgo --noEmit
-ExitStatus:: DiagnosticsPresent_OutputsSkipped
+ExitStatus:: DiagnosticsPresent_OutputsGenerated
Output::
[96ma.ts[0m:[93m1[0m:[93m7[0m - [91merror[0m[90m TS4094: [0mProperty 'p' of exported anonymous class type may not be private or protected.
@@ -118,7 +118,7 @@ Edit [5]:: Introduce error
const a = class { private p = 10; };
tsgo --noEmit
-ExitStatus:: DiagnosticsPresent_OutputsSkipped
+ExitStatus:: DiagnosticsPresent_OutputsGenerated
Output::
[96ma.ts[0m:[93m1[0m:[93m7[0m - [91merror[0m[90m TS4094: [0mProperty 'p' of exported anonymous class type may not be private or protected.
@@ -164,7 +164,7 @@ const a = class {
Edit [7]:: no change
tsgo --noEmit
-ExitStatus:: DiagnosticsPresent_OutputsSkipped
+ExitStatus:: DiagnosticsPresent_OutputsGenerated
Output::
[96ma.ts[0m:[93m1[0m:[93m7[0m - [91merror[0m[90m TS4094: [0mProperty 'p' of exported anonymous class type may not be private or protected.
diff --git a/testdata/baselines/reference/tsc/noEmit/semantic-errors.js b/testdata/baselines/reference/tsc/noEmit/semantic-errors.js
index 96ff47848c8..78f6e09630f 100644
--- a/testdata/baselines/reference/tsc/noEmit/semantic-errors.js
+++ b/testdata/baselines/reference/tsc/noEmit/semantic-errors.js
@@ -12,7 +12,7 @@ const a: number = "hello"
}
tsgo --noEmit
-ExitStatus:: DiagnosticsPresent_OutputsSkipped
+ExitStatus:: DiagnosticsPresent_OutputsGenerated
Output::
[96ma.ts[0m:[93m1[0m:[93m7[0m - [91merror[0m[90m TS2322: [0mType 'string' is not assignable to type 'number'.
@@ -51,7 +51,7 @@ declare const console: { log(msg: any): void; };
Edit [0]:: no change
tsgo --noEmit
-ExitStatus:: DiagnosticsPresent_OutputsSkipped
+ExitStatus:: DiagnosticsPresent_OutputsGenerated
Output::
[96ma.ts[0m:[93m1[0m:[93m7[0m - [91merror[0m[90m TS2322: [0mType 'string' is not assignable to type 'number'.
@@ -107,7 +107,7 @@ Edit [5]:: Introduce error
const a: number = "hello"
tsgo --noEmit
-ExitStatus:: DiagnosticsPresent_OutputsSkipped
+ExitStatus:: DiagnosticsPresent_OutputsGenerated
Output::
[96ma.ts[0m:[93m1[0m:[93m7[0m - [91merror[0m[90m TS2322: [0mType 'string' is not assignable to type 'number'.
@@ -140,7 +140,7 @@ Found 1 error in a.ts[90m:1[0m
Edit [7]:: no change
tsgo --noEmit
-ExitStatus:: DiagnosticsPresent_OutputsSkipped
+ExitStatus:: DiagnosticsPresent_OutputsGenerated
Output::
[96ma.ts[0m:[93m1[0m:[93m7[0m - [91merror[0m[90m TS2322: [0mType 'string' is not assignable to type 'number'.
diff --git a/testdata/baselines/reference/tsc/noEmit/syntax-errors.js b/testdata/baselines/reference/tsc/noEmit/syntax-errors.js
index 5f1f5d6e7c4..8e28f48d7b3 100644
--- a/testdata/baselines/reference/tsc/noEmit/syntax-errors.js
+++ b/testdata/baselines/reference/tsc/noEmit/syntax-errors.js
@@ -12,7 +12,7 @@ const a = "hello
}
tsgo --noEmit
-ExitStatus:: DiagnosticsPresent_OutputsSkipped
+ExitStatus:: DiagnosticsPresent_OutputsGenerated
Output::
[96ma.ts[0m:[93m1[0m:[93m17[0m - [91merror[0m[90m TS1002: [0mUnterminated string literal.
@@ -51,7 +51,7 @@ declare const console: { log(msg: any): void; };
Edit [0]:: no change
tsgo --noEmit
-ExitStatus:: DiagnosticsPresent_OutputsSkipped
+ExitStatus:: DiagnosticsPresent_OutputsGenerated
Output::
[96ma.ts[0m:[93m1[0m:[93m17[0m - [91merror[0m[90m TS1002: [0mUnterminated string literal.
@@ -107,7 +107,7 @@ Edit [5]:: Introduce error
const a = "hello
tsgo --noEmit
-ExitStatus:: DiagnosticsPresent_OutputsSkipped
+ExitStatus:: DiagnosticsPresent_OutputsGenerated
Output::
[96ma.ts[0m:[93m1[0m:[93m17[0m - [91merror[0m[90m TS1002: [0mUnterminated string literal.
@@ -143,7 +143,7 @@ const a = "hello;
Edit [7]:: no change
tsgo --noEmit
-ExitStatus:: DiagnosticsPresent_OutputsSkipped
+ExitStatus:: DiagnosticsPresent_OutputsGenerated
Output::
[96ma.ts[0m:[93m1[0m:[93m17[0m - [91merror[0m[90m TS1002: [0mUnterminated string literal.