'`tsc` cannot find self-defined declaration files (.d.ts)
0. Prequisitions
[email protected]- Editor: VSCode 1.15.7
- OS: Ubuntu 20.04
1. Project Structure
I create a minimalist TypeScript project whose structure looks like this:
. // Project root directory ($PWD)
├── dist
│ └── main.js // output file
├── Makefile
├── package.json
├── package-lock.json
├── src
│ ├── main.ts
│ └── types
│ └── window.d.ts // ←extends some properties to `global.Window`
└── tsconfig.json
2. Customize Interface global.Window
I extends some customized properties attached on built-in Window global interface:
// window.d.ts
export { } // to solve TS2669, see https://stackoverflow.com/questions/57132428/augmentations-for-the-global-scope-can-only-be-directly-nested-in-external-modul
declare global {
interface OurDefinedGlobalRuntimeEnv {
/** Runtime value (Defined in preload.js)
* - `web`: Ordinary web browser.
* - `electron`: Electron renderer window.
*/
BROWSER: 'electron' | 'web' | undefined
SERVER_IP: string
DEBUG: string
NODE_ENV: node_env_t,
}
type node_env_t = 'production' | 'development'
interface Window {
__RUNTIME_ENV__: OurDefinedGlobalRuntimeEnv
}
}
Then inject our self-defined object into window:
// main.ts
type inferPropType<T, K extends keyof T> = T[K]
const rtenv1: inferPropType<Window, '__RUNTIME_ENV__'> = {
BROWSER: 'electron',
NODE_ENV: process.env.NODE_ENV === 'development' ? 'development' : 'production',
SERVER_IP: process.env.SERVER_IP || '',
DEBUG: process.env.DEBUG || '',
ENV_VAR: process.env,
}
const rtenv2: OurDefinedGlobalRuntimeEnv = rtenv1
window.__RUNTIME_ENV__ = rtenv1
3. VSCode IntelliSense & tsc
So far, VSCode's IntelliSense doesn't output any error or warning, and type can be inferred by IntelliSense correctly:

And run tsc with the root path of the project as $CWD:
cd PROJECT_ROOT_DIR
npx tsc --outDir ./dist/ --module commonjs ./src/*.ts
4. Where The Problem Is?
After debugging for > 7 hours, I found tsc cannot detect *.d.ts when the file want to be compiled and *.d.ts are not in the same folder. That is to say, if move window.d.ts:
.
└── src
├── main.ts
└── types
└── window.d.ts
become this:
.
└── src
├── main.ts
└── window.d.ts
Now tsc compilation passed:
npx tsc --outDir ./dist/ --module commonjs ./src/*.ts
5. Questions
- In TypeScript official document, it seems own-defined
*.d.tscan be placed in any sub folder of the project? - VSCode's IntelliSense can correctly load and infer the types defined in our
*.d.tsand the extended globalWindowinterface, so I guess I didn't wrote the definition file wrongly...right?
The types defined in our
window.d.tswill be used by multiple entry files, in this case I should not copy thiswindow.d.tsto multiple folders.(NOTE: This is merely a minimalist project to reproduce the issue, so I only wrote one entry file
main.ts. In real world, this is actually a large Electron project which contains other entries files likepreload.jsandelectron_entry.jsand a SPA entry bundled by Webpack...etc)
Does
tsc --outDir OUT_DIR SRC_FILEalways ignores${PWD}/tsconfig.jsonunless I usetsc --project ./tsconfig.jsonor justtsc(will compile everything according totsconfig.json)? I wonder know if I can just build **on specific.tsfile viatsc XXXX...directly ** WITHOUT create multipletsconfig.jsonnor viawebpack.Although I found use
tsc(without any parameters) can compile successfully (it loadstsconfig.jsonimplicitly), but I don't know how it succeeded nor which option intsconfig.jsonmade it successful... Even with params--baseUrl . --rootDir . --moduleResolution Node --module commonjsstill cannot loadwindow.d.ts. `
Solution 1:[1]
since it is not referenced anywhere under the root path, the compiler is not aware of the existence of the global declaration file so you need to pass its path in addition to the root path (tsc gets set of TypeScript files)
so in your scenario, following would work:
npx tsc --outDir ./dist/ --module commonjs ./src/*.ts ./src/types/window.d.ts.
Solution 2:[2]
The command your are running : npx tsc --outDir ./dist/ --module commonjs ./src/*.ts is wrong. Here you are asking TypeScript to *only compile files under src/*.ts.
Fix
Compile with tsconfig i.e. npx tsc -p ./tsconfig.json. Or even npx tsc as it will pickup tsconfig.json by default ?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | basarat |


