This is a follow up to How to use node-config in typescript? since I couldn't find a proper answer.
I'm relatively new to TS and I'm trying to convert our configs from json to typescript, while trying to incorporate types on the config.
What we currently have is something like:
// default.json
{
"server": {
"timeout": 10
}
}
// some-code.ts
import config from 'config';
...
const serverTimeout = config.get<number>('server.timeout'); // 10
Here, we are able to get required configs, but we need to specify the type via generics in code. I'm trying to incorporate (relatively) stronger typing.
Dry conversion:
// default.ts
import { MyConfig } from './config-schema.ts'
const conf: MyConfig = {
"server": {
"timeout": 10
}
};
export default conf;
// config-schema.ts
export interface MyConfig {
server: {
timeout: number;
}
}
// some-code.ts
import config from 'config';
console.log(config); // { "server": { "timeout": 10 } }
console.log(config.get<number>('server.timeout')); // 10
console.log((config as any).server.timeout); // 10
console.log(config.server.timeout); // obviously a compile time error.
As you can see, the last form will NOT work and results in compile time ERROR. I somehow want config
to conform to the shape of MyConfig
so that config.server.timeout
is possible with strong type number
.
I need to somehow extend the IConfig
interface with MyConfig
or force a re-typing of config
to IConfig & MyConfig
.
My attempt:
// config-schema.ts
import config from 'config';
interface MyConfig {
server: {
timeout: number;
}
}
export (config as any as MyConfig);
// some-code.ts
import config from './config-schema';
console.log(config.server.timeout); // 10
This works, but somehow doesn't feel right to me.
Problems
- Forced to use
any
... can this be avoided somehow ? - Need to do something like
import config from '../../core/config-schema';
-> looks ugly, path different for different files, need all project collaborators to follow convention... is it possible to keep it asimport config from 'config';
and have the magic abstracted out ? - Compile
default.ts
todefault.js
withtsc
at compile time (so that typescript is not a runtime dependency). Have updated env varNODE_CONFIG_DIR
accordingly. Currently I do this, but the config object gets created with an extra hierarchy level. i.e. instead ofconfig.server.timeout
, it becameconfig.default.server.timeout
Edit: Third question resolved -- see comment