How to use node-config in typescript?
Solution 1
config.get utility can be used to get the config values like so:
import config from 'config';
const port: number = config.get('server.port');
Solution 2
I'm taking a slightly different approach - defining the variables in JavaScript, and accessing them in TypeScript.
Using the following folder structure:
├── config
│ ├── custom-environment-variables.js
│ ├── default.js
│ ├── development.js
│ └── production.js
└── server
├── config.ts
└── main.ts
I define the configuration in the root config/ folder. For example:
// config/default.js
module.exports = {
cache: false,
port: undefined // Setting to undefined ensures the environment config must define it
};
// config/development.js
module.exports = {
port: '3000'
}
// config/production.js
module.exports = {
cache: true
}
// config/custom-environment-variables.js
module.exports = {
port: 'PORT'
}
Now, in TypeScript land, I define an interface to provide nicer autocomplete & documentation, and write some bridging code to pull in the config from node-config into my config map:
// server/config.ts
import nodeConfig from 'config';
interface Config {
/** Whether assets should be cached or not. */
cache: boolean;
/** The port that the express server should bind to. */
port: string;
}
const config: Config = {
cache: nodeConfig.get<boolean>('cache'),
port: nodeConfig.get<string>('port')
};
export default config;
Finally, I can now import and use my config variables inside any TypeScript code.
// server/main.ts
import express from 'express';
import config from './config';
const { port } = config;
const app = express();
app.listen(port);
This approach has the following benefits:
- We can use the rich and battle-tested features available from
node-configwithout needing to re-invent the wheel - We have a strongly-typed, well documented config map which can be imported and used from anywhere inside our TS code
Solution 3
Use this "import * as config from 'config';" instead of "import config from 'config';"
import * as config from 'config';
const port = config.get('server.port');
console.log('port', port);
// port 4000
config/development.json
{
"server": {
"port": 4000
}
}
and set NODE_ENV=development
export NODE_ENV=development
note: No need this NODE_ENV set if you use default
Solution 4
From the previous, I was still having trouble where config was not able to find the server key from default.ts.
Below is how I am using npm config module. Updated export default { to export =:
// default.ts
export = {
server: {
port: 4000,
},
logLevel: 'error',
};
Usage within the app [Same]:
import config from 'config';
console.log(config.get('server'));
Solution 5
I use IConfig interface, so I can set the config path first:
import { IConfig } from 'config';
export function dosomething() {
process.env["NODE_CONFIG_DIR"] = 'path to config dir';
//using get
const config: IConfig = require("config");
const port = config.get('server.port');
console.log('port', port);
//using custom schema
const config2: { server: { port: number } } = require("config");
console.log('config2.server.port', config2.server.port);
}
//port 4000
//config2.server.port 4000
Related videos on Youtube
Deepak
Updated on September 16, 2022Comments
-
Deepak 3 monthsAfter installing
node-configand@types/config:yarn add config yarn add --dev @types/configAnd adding config as described in lorenwest/node-config:
// default.ts export default { server: { port: 4000, }, logLevel: 'error', };When I am trying to use in my app:
import config from 'config'; console.log(config.server);I am getting the error:
src/app.ts(19,53): error TS2339: Property 'server' does not exist on type 'IConfig'. -
Deepak over 4 yearsIt is just a workaround. still looking for better answer. -
Estus Flask over 4 yearsThis is how config is expected to be used.getandhasare actual reasons to use it. It provides too much magic to be properly typed. You could extend its type likeconst config: IConfig & MySchema = require('config')or with custom d.ts typing, but you cannot be sure that expected properties are there because they can exist in one config but not in another. -
Fedoranimus about 3 yearsNot sure what a "better answer" would look like, but it's important to note that
config.get()supports generics. You could doconfig.get<number>('server.port')and that might be a little cleaner in some instances. -
Ernest Jones 8 months
-
Emmanuel Meric de Bellefon 7 monthsautomatic typing could be certainly implemented in the library using ts template litterals