TypeScript only uses one tsconfig.json and doesn’t automatically use subdirectories’ tsconfig.json for the files there. However, you can use project references for this.
Create a directory structure like this:
.
├── tsconfig.json
├── tsconfig.settings.json (optional)
└── foo/
├── node-file.ts
├── tsconfig.json ("module": "commonjs")
└── bar/
├── browser-file.ts
└── tsconfig.json ("module": "esnext")
tsconfig.json
{
"files": [],
"references": [
{"path": "./foo"},
{"path": "./foo/bar"}
]
}
This is the root tsconfig.json. When you run tsc --build (see below) in the root directory, TypeScript will build the referenced projects ./foo/tsconfig.json and ./foo/bar/tsconfig.json.
The "files": [] is to stop accidental tscs without --build from attempting to compile everything in the root directory, which will error but create multiple .js files in possibly the incorrect places.
tsconfig.settings.json (optional)
{
"compilerOptions": {
"strict": true,
"noImplicitReturns": true
}
}
You can put configuration common to foo and foo/bar and extend this configuration with extends to reduce duplication. Note that all relative paths in here will be resolved relative to tsconfig.settings.json when extended, so something like "outDir": "dist" may not work as expected.
foo/tsconfig.json
{
"extends": "../tsconfig.settings.json",
"exclude": ["bar/**/*.ts"],
"compilerOptions": {
"module": "commonjs"
}
}
This is the configuration for the CommonJS files. It also extends the common config and excludes the files in foo/bar.
foo/bar/tsconfig.json
{
"extends": "../../tsconfig.settings.json",
"compilerOptions": {
"module": "esnext"
}
}
This is pretty similar to foo’s configuration.
Building
To compile foo and foo/bar at the same time, use build mode from the root directory:
tsc --build # or tsc -b
# Watch mode:
tsc --build --watch # or tsc -bw
From the handbook:
A long-awaited feature is smart incremental builds for TypeScript projects. In 3.0 you can use the --build flag with tsc. This is effectively a new entry point for tsc that behaves more like a build orchestrator than a simple compiler.
Running tsc --build (tsc -b for short) will do the following:
- Find all referenced projects
- Detect if they are up-to-date
- Build out-of-date projects in the correct order
You can provide tsc -b with multiple config file paths (e.g. tsc -b src test). Just like tsc -p, specifying the config file name itself is unnecessary if it’s named tsconfig.json.
You can also compile individual projects:
tsc -b foo # or cd foo && tsc -b
tsc -b foo/bar # or cd foo/bar && tsc -b
Note that are some build-only flags and you cannot override compiler options with command-line arguments.
tsconfig.jsonand doesn't automatically use subdirectories'tsconfig.jsonfor the files there. You may want to look into project referencestscdoesn't support this beahviour means that we can't easily type-check our codebases in a way that reports the exact same errors as our IDEs by default. This is sooo annoying and makes setting up monorepo projects unnecessarily challenging. The "simplest" workaround is to create additionaltsconfig.<something>.jsonfiles that include only the files that are not included by nestedtsconfigfiles and then runtsc -pfor each of them...