0. Prequisitions
typescript@4.3.4
- 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.ts
can be placed in any sub folder of the project? - VSCode's IntelliSense can correctly load and infer the types defined in our
*.d.ts
and the extended globalWindow
interface, so I guess I didn't wrote the definition file wrongly...right?
The types defined in our
window.d.ts
will be used by multiple entry files, in this case I should not copy thiswindow.d.ts
to 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.js
andelectron_entry.js
and a SPA entry bundled by Webpack...etc)
Does
tsc --outDir OUT_DIR SRC_FILE
always ignores${PWD}/tsconfig.json
unless I usetsc --project ./tsconfig.json
or justtsc
(will compile everything according totsconfig.json
)? I wonder know if I can just build **on specific.ts
file viatsc XXXX...
directly ** WITHOUT create multipletsconfig.json
nor viawebpack
.Although I found use
tsc
(without any parameters) can compile successfully (it loadstsconfig.json
implicitly), but I don't know how it succeeded nor which option intsconfig.json
made it successful... Even with params--baseUrl . --rootDir . --moduleResolution Node --module commonjs
still cannot loadwindow.d.ts
. `