# Proposal To better support the development and consumption of node.js modules in TypeScript, I propose that we add the ability to emit a single declaration file for a node.js package. To that end, I suggest we add the following features: - Add a `packageName` compiler option, used to specify the name of the node.js package. - Add a `packageMain` compiler option, used to specify the path to the main typescript module for the package. - Add a `packageDeclaration` compiler option, used to specify the output path of the declaration file for the package. - When the above three options are supplied, along with `declaration` and either `module` or a `target` of `ES6`, we should emit a single declaration file for the program inputs. The output for a `packageDeclaration` would have the following form: - Exports for the main module will be defined inside of an _ambient external module_ that has the name provided via `packageName`. - Exports for relative modules will be defined inside of an _ambient external module_ that has a name derived from the package name, and the path of the module relative to the nearest `package.json` file, common directory path, or the current directory. # Example Given the following sources: **a.ts** ``` ts import { C } from "./lib/b"; export function func(): C { return new C(); } ``` **lib\b.ts** ``` ts export class C { } ``` **index.ts** ``` ts export * from "./a"; ``` And the following command line: ``` tsc index.ts a.ts lib/b.ts --module commonjs --declaration --packageName sample --packageMain index.ts --packageDeclaration sample.d.ts ``` You would get the following package declaration output file: **sample.d.ts** ``` ts declare module "sample" { export * from "sample/a"; } declare module "sample/a" { import { C } from "sample/lib/b"; function func(): C; } declare module "sample/lib/b" { class C { } } ``` # Out of scope It would be nice to also be able to emit only the exports visible from the main module, and reduce the overall output side of the declaration file, but not all node.js packages are designed to work that way. Instead, in the future we could investigate an option to choose whether to emit a single ambient module declaration. The proposed approach can be used whether you intend to have a single output module or the ability to reach nested submodules, while the more restrictive approach would alienate some package authors. It is also out of scope to infer package information from the `package.json` file, although that may be considered in the future. That might look something like having a `package` compiler option that can read the `package.json` file to infer the `packageName` from the `"name"` field of the package, and the `packageDeclaration` from the `"typings"` (proposed) field of the package. However, its more complicated to derive `packageMain` as the `"main"` field of the package will be pointing to the output file and not the original typescript file. We might have to propose a `"devMain"`, or some other similarly named field, to satisfy this requirement. As proposed, using `packageDeclaration` will circumvent regular declaration file generation. We could opt to support both, by writing individual declaration files for each non-declaration input as well as the package-level declaration, though I am not certain whether that would be necessary. A sample implementation for this proposal can be found in the [packageDeclaration2](https://github.com/Microsoft/TypeScript/tree/packageDeclaration2) branch.