TypeScript configuration
Other tools try to infer TypeScript types directly from a configuration schema. While it’s impressive how far this approach has come since the early days, the types used during inference are extremely complex and there are always going to be limitations. Plus importing these config tools directly into your code can introduce headaches with ESM/commonjs and tsconfig files.
Instead, while DMNO still uses TypeScript to define your schema in your .dmno/config.mts
files, it is decoupled from your code. We run our own build process using Vite that just works without any configuration problems, and we generate .d.ts
files with built-in documentation (JSDoc comments) to be consumed by your code. Our type system is also much more powerful, with an inheritance mechanism not possible in other systems.
Example of VSCode’s IntelliSense using DMNO’s generated types:
Accessing the types in your code
To simplify accessing your config, we inject the DMNO_CONFIG
and DMNO_PUBLIC_CONFIG
globals. We must let TypeScript know about them in order to allow type-checking when using your config and to get autocompletion/IntelliSense in your IDE.
The DMNO Config loader automaticaly generates TS types to be consumed by your code into the .dmno/.typegen
directory:
.dmno/.typegen/global.d.ts
- injects theDMNO_CONFIG
global.dmno/.typegen/global-public.d.ts
- injects theDMNO_PUBLIC_CONFIG
global.dmno/schema.ts
- the actual schema of your config, used by the.d.ts
files
We use these same types to give you autocompletion when authoring your schema itself.
The easiest way to let TypeScript know about them is to create a dmno-env.d.ts
file in your source code that imports them via triple-slash references.
However in some rare cases - like where you have some set of isolated source files split from the rest of your code, you may need to be a bit more explicit. You can do this by adding references to the generated type files either in your tsconfig or in a specific source file directly.
For example, in your tsconfig:
Or in a specific file:
Pure JS projects
Even if you are not writing TypeScript, these days you are still likely relying on TypeScript for autocompletion in your IDE. If you don’t use a jsconfig.json
file, your editor will likely just pick up the dmno-env.d.ts
file automatically. But if you do have one, you might need to explicitly add it to your include
globs. For example:
Injecting DMNO_CONFIG
vs DMNO_PUBLIC_CONFIG
To keep things simple, by default we always inject the global types for both DMNO_CONFIG
and DMNO_PUBLIC_CONFIG
. However, there are cases where you may want to only inject one or the other:
- In a front-end only (i.e., non-SSR) context, you could skip injecting
DMNO_CONFIG
because you’ll only want to use non-sensitive config items. That said, injecting the types doesn’t actually inject your sensitive secrets, and we inject a placeholder proxy throws a helpful error if you try to useDMNO_CONFIG
. - In a back-end only context, you could skip injecting
DMNO_PUBLIC_CONFIG
and exclusively useDMNO_CONFIG
- just like we do in your.dmno/config.mts
file. However, there isn’t really any harm in using the public version, and it can serve as an extra check that something is definitely not sensitive - which is useful if you were, for example, returning a config item in an API response.