diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 86d073f7d49..d29a287b950 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -17,6 +17,12 @@ namespace ts { type: "boolean", description: Diagnostics.Generates_corresponding_d_ts_file, }, + { + name: "declarationDir", + type: "string", + isFilePath: true, + paramType: Diagnostics.DIRECTORY, + }, { name: "diagnostics", type: "boolean", diff --git a/src/compiler/types.ts b/src/compiler/types.ts index ca662d6ac46..c065478a20a 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2371,6 +2371,7 @@ namespace ts { allowNonTsExtensions?: boolean; charset?: string; declaration?: boolean; + declarationDir?: string; diagnostics?: boolean; emitBOM?: boolean; help?: boolean; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index d8474f85f6b..40b5462888e 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2012,6 +2012,16 @@ namespace ts { return emitOutputFilePathWithoutExtension + extension; } + export function getDeclarationEmitOutputFilePath(sourceFile: SourceFile, host: EmitHost) { + const options = host.getCompilerOptions(); + const outputDir = options.declarationDir || options.outDir; // Prefer declaration folder if specified + return options.declaration ? removeFileExtension( + outputDir + ? getSourceFilePathInNewDir(sourceFile, host, outputDir) + : sourceFile.fileName + ) + ".d.ts" : undefined; + } + export function getEmitScriptTarget(compilerOptions: CompilerOptions) { return compilerOptions.target || ScriptTarget.ES3; } @@ -2065,23 +2075,23 @@ namespace ts { const emitFileNames: EmitFileNames = { jsFilePath, sourceMapFilePath: getSourceMapFilePath(jsFilePath, options), - declarationFilePath: !isSourceFileJavaScript(sourceFile) ? getDeclarationEmitFilePath(jsFilePath, options) : undefined + declarationFilePath: !isSourceFileJavaScript(sourceFile) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined }; action(emitFileNames, [sourceFile], /*isBundledEmit*/false); } function onBundledEmit(host: EmitHost) { // Can emit only sources that are not declaration file and are either non module code or module with --module or --target es6 specified - const bundledSources = filter(host.getSourceFiles(), - sourceFile => !isDeclarationFile(sourceFile) && // Not a declaration file - (!isExternalModule(sourceFile) || // non module file - (getEmitModuleKind(options) && isExternalModule(sourceFile)))); // module that can emit - note falsy value from getEmitModuleKind means the module kind that shouldn't be emitted + const bundledSources = filter(host.getSourceFiles(), sourceFile => + !isDeclarationFile(sourceFile) // Not a declaration file + && (!isExternalModule(sourceFile) || !!getEmitModuleKind(options))); // and not a module, unless module emit enabled + if (bundledSources.length) { const jsFilePath = options.outFile || options.out; const emitFileNames: EmitFileNames = { jsFilePath, sourceMapFilePath: getSourceMapFilePath(jsFilePath, options), - declarationFilePath: getDeclarationEmitFilePath(jsFilePath, options) + declarationFilePath: options.declaration ? removeFileExtension(jsFilePath) + ".d.ts" : undefined }; action(emitFileNames, bundledSources, /*isBundledEmit*/true); } @@ -2090,10 +2100,6 @@ namespace ts { function getSourceMapFilePath(jsFilePath: string, options: CompilerOptions) { return options.sourceMap ? jsFilePath + ".map" : undefined; } - - function getDeclarationEmitFilePath(jsFilePath: string, options: CompilerOptions) { - return options.declaration ? removeFileExtension(jsFilePath) + ".d.ts" : undefined; - } } export function getSourceFilePathInNewDir(sourceFile: SourceFile, host: EmitHost, newDirPath: string) {