Skip to content

Commit 6496b0b

Browse files
nojvekmhegazy
authored andcommitted
--emitDeclarationsOnly flag to enable declarations only output (#20735)
* Add emitOnlyDeclarations flag * Fix name * verifyOptions checking logic * Passing tests * doJsEmitBaseline * Tests !!!
1 parent f13f093 commit 6496b0b

20 files changed

+186
-5
lines changed

src/compiler/commandLineParser.ts

+6
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@ namespace ts {
186186
category: Diagnostics.Basic_Options,
187187
description: Diagnostics.Generates_corresponding_d_ts_file,
188188
},
189+
{
190+
name: "emitDeclarationsOnly",
191+
type: "boolean",
192+
category: Diagnostics.Advanced_Options,
193+
description: Diagnostics.Only_emit_d_ts_declaration_files,
194+
},
189195
{
190196
name: "sourceMap",
191197
type: "boolean",

src/compiler/diagnosticMessages.json

+4
Original file line numberDiff line numberDiff line change
@@ -2807,6 +2807,10 @@
28072807
"category": "Message",
28082808
"code": 6013
28092809
},
2810+
"Only emit '.d.ts' declaration files.": {
2811+
"category": "Message",
2812+
"code": 6014
2813+
},
28102814
"Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'.": {
28112815
"category": "Message",
28122816
"code": 6015

src/compiler/emitter.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ namespace ts {
135135

136136
function emitSourceFileOrBundle({ jsFilePath, sourceMapFilePath, declarationFilePath }: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle) {
137137
// Make sure not to write js file and source map file if any of them cannot be written
138-
if (!host.isEmitBlocked(jsFilePath) && !compilerOptions.noEmit) {
138+
if (!host.isEmitBlocked(jsFilePath) && !compilerOptions.noEmit && !compilerOptions.emitDeclarationsOnly) {
139139
if (!emitOnlyDtsFiles) {
140140
printSourceFileOrBundle(jsFilePath, sourceMapFilePath, sourceFileOrBundle);
141141
}

src/compiler/program.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -2201,6 +2201,16 @@ namespace ts {
22012201
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "checkJs", "allowJs"));
22022202
}
22032203

2204+
if (options.emitDeclarationsOnly) {
2205+
if (!options.declaration) {
2206+
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDeclarationsOnly", "declarations");
2207+
}
2208+
2209+
if (options.noEmit) {
2210+
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "emitDeclarationsOnly", "noEmit");
2211+
}
2212+
}
2213+
22042214
if (options.emitDecoratorMetadata &&
22052215
!options.experimentalDecorators) {
22062216
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators");
@@ -2223,7 +2233,9 @@ namespace ts {
22232233
const emitHost = getEmitHost();
22242234
const emitFilesSeen = createMap<true>();
22252235
forEachEmittedFile(emitHost, (emitFileNames) => {
2226-
verifyEmitFilePath(emitFileNames.jsFilePath, emitFilesSeen);
2236+
if (!options.emitDeclarationsOnly) {
2237+
verifyEmitFilePath(emitFileNames.jsFilePath, emitFilesSeen);
2238+
}
22272239
verifyEmitFilePath(emitFileNames.declarationFilePath, emitFilesSeen);
22282240
});
22292241
}

src/compiler/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -3972,6 +3972,7 @@ namespace ts {
39723972
/** configFile is set as non enumerable property so as to avoid checking of json source files */
39733973
/* @internal */ readonly configFile?: JsonSourceFile;
39743974
declaration?: boolean;
3975+
emitDeclarationsOnly?: boolean;
39753976
declarationDir?: string;
39763977
/* @internal */ diagnostics?: boolean;
39773978
/* @internal */ extendedDiagnostics?: boolean;

src/harness/harness.ts

+13-3
Original file line numberDiff line numberDiff line change
@@ -1252,8 +1252,18 @@ namespace Harness {
12521252
options: ts.CompilerOptions,
12531253
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
12541254
currentDirectory: string): DeclarationCompilationContext | undefined {
1255-
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length !== result.files.length) {
1256-
throw new Error("There were no errors and declFiles generated did not match number of js files generated");
1255+
1256+
if (result.errors.length === 0) {
1257+
if (options.declaration) {
1258+
if (options.emitDeclarationsOnly) {
1259+
if (result.files.length > 0 || result.declFilesCode.length === 0) {
1260+
throw new Error("Only declaration files should be generated when emitDeclarationsOnly:true");
1261+
}
1262+
}
1263+
else if (result.declFilesCode.length !== result.files.length) {
1264+
throw new Error("There were no errors and declFiles generated did not match number of js files generated");
1265+
}
1266+
}
12571267
}
12581268

12591269
const declInputFiles: TestFile[] = [];
@@ -1654,7 +1664,7 @@ namespace Harness {
16541664
}
16551665

16561666
export function doJsEmitBaseline(baselinePath: string, header: string, options: ts.CompilerOptions, result: CompilerResult, tsConfigFiles: Harness.Compiler.TestFile[], toBeCompiled: Harness.Compiler.TestFile[], otherFiles: Harness.Compiler.TestFile[], harnessSettings: Harness.TestCaseParser.CompilerSettings) {
1657-
if (!options.noEmit && result.files.length === 0 && result.errors.length === 0) {
1667+
if (!options.noEmit && !options.emitDeclarationsOnly && result.files.length === 0 && result.errors.length === 0) {
16581668
throw new Error("Expected at least one js file to be emitted or at least one error to be created.");
16591669
}
16601670

tests/baselines/reference/api/tsserverlibrary.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -2266,6 +2266,7 @@ declare namespace ts {
22662266
charset?: string;
22672267
checkJs?: boolean;
22682268
declaration?: boolean;
2269+
emitDeclarationsOnly?: boolean;
22692270
declarationDir?: string;
22702271
disableSizeLimit?: boolean;
22712272
downlevelIteration?: boolean;

tests/baselines/reference/api/typescript.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -2266,6 +2266,7 @@ declare namespace ts {
22662266
charset?: string;
22672267
checkJs?: boolean;
22682268
declaration?: boolean;
2269+
emitDeclarationsOnly?: boolean;
22692270
declarationDir?: string;
22702271
disableSizeLimit?: boolean;
22712272
downlevelIteration?: boolean;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//// [helloworld.ts]
2+
const Log = {
3+
info(msg: string) {}
4+
}
5+
6+
class HelloWorld {
7+
constructor(private name: string) {
8+
}
9+
10+
public hello() {
11+
Log.info(`Hello ${this.name}`);
12+
}
13+
}
14+
15+
16+
17+
18+
//// [helloworld.d.ts]
19+
declare const Log: {
20+
info(msg: string): void;
21+
};
22+
declare class HelloWorld {
23+
private name;
24+
constructor(name: string);
25+
hello(): void;
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
=== tests/cases/compiler/helloworld.ts ===
2+
const Log = {
3+
>Log : Symbol(Log, Decl(helloworld.ts, 0, 5))
4+
5+
info(msg: string) {}
6+
>info : Symbol(info, Decl(helloworld.ts, 0, 13))
7+
>msg : Symbol(msg, Decl(helloworld.ts, 1, 7))
8+
}
9+
10+
class HelloWorld {
11+
>HelloWorld : Symbol(HelloWorld, Decl(helloworld.ts, 2, 1))
12+
13+
constructor(private name: string) {
14+
>name : Symbol(HelloWorld.name, Decl(helloworld.ts, 5, 14))
15+
}
16+
17+
public hello() {
18+
>hello : Symbol(HelloWorld.hello, Decl(helloworld.ts, 6, 3))
19+
20+
Log.info(`Hello ${this.name}`);
21+
>Log.info : Symbol(info, Decl(helloworld.ts, 0, 13))
22+
>Log : Symbol(Log, Decl(helloworld.ts, 0, 5))
23+
>info : Symbol(info, Decl(helloworld.ts, 0, 13))
24+
>this.name : Symbol(HelloWorld.name, Decl(helloworld.ts, 5, 14))
25+
>this : Symbol(HelloWorld, Decl(helloworld.ts, 2, 1))
26+
>name : Symbol(HelloWorld.name, Decl(helloworld.ts, 5, 14))
27+
}
28+
}
29+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
=== tests/cases/compiler/helloworld.ts ===
2+
const Log = {
3+
>Log : { info(msg: string): void; }
4+
>{ info(msg: string) {}} : { info(msg: string): void; }
5+
6+
info(msg: string) {}
7+
>info : (msg: string) => void
8+
>msg : string
9+
}
10+
11+
class HelloWorld {
12+
>HelloWorld : HelloWorld
13+
14+
constructor(private name: string) {
15+
>name : string
16+
}
17+
18+
public hello() {
19+
>hello : () => void
20+
21+
Log.info(`Hello ${this.name}`);
22+
>Log.info(`Hello ${this.name}`) : void
23+
>Log.info : (msg: string) => void
24+
>Log : { info(msg: string): void; }
25+
>info : (msg: string) => void
26+
>`Hello ${this.name}` : string
27+
>this.name : string
28+
>this : this
29+
>name : string
30+
}
31+
}
32+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
error TS5052: Option 'emitDeclarationsOnly' cannot be specified without specifying option 'declarations'.
2+
3+
4+
!!! error TS5052: Option 'emitDeclarationsOnly' cannot be specified without specifying option 'declarations'.
5+
==== tests/cases/compiler/hello.ts (0 errors) ====
6+
var hello = "yo!";
7+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
=== tests/cases/compiler/hello.ts ===
2+
var hello = "yo!";
3+
>hello : Symbol(hello, Decl(hello.ts, 0, 3))
4+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
=== tests/cases/compiler/hello.ts ===
2+
var hello = "yo!";
3+
>hello : string
4+
>"yo!" : "yo!"
5+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error TS5052: Option 'emitDeclarationsOnly' cannot be specified without specifying option 'declarations'.
2+
error TS5053: Option 'emitDeclarationsOnly' cannot be specified with option 'noEmit'.
3+
4+
5+
!!! error TS5052: Option 'emitDeclarationsOnly' cannot be specified without specifying option 'declarations'.
6+
!!! error TS5053: Option 'emitDeclarationsOnly' cannot be specified with option 'noEmit'.
7+
==== tests/cases/compiler/hello.ts (0 errors) ====
8+
var hello = "yo!";
9+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
=== tests/cases/compiler/hello.ts ===
2+
var hello = "yo!";
3+
>hello : Symbol(hello, Decl(hello.ts, 0, 3))
4+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
=== tests/cases/compiler/hello.ts ===
2+
var hello = "yo!";
3+
>hello : string
4+
>"yo!" : "yo!"
5+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// @declaration: true
2+
// @emitDeclarationsOnly: true
3+
4+
// @filename: helloworld.ts
5+
const Log = {
6+
info(msg: string) {}
7+
}
8+
9+
class HelloWorld {
10+
constructor(private name: string) {
11+
}
12+
13+
public hello() {
14+
Log.info(`Hello ${this.name}`);
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// @emitDeclarationsOnly: true
2+
3+
// @filename: hello.ts
4+
var hello = "yo!";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// @noEmit: true
2+
// @emitDeclarationsOnly: true
3+
4+
// @filename: hello.ts
5+
var hello = "yo!";

0 commit comments

Comments
 (0)