How to use node-config in typescript?

Deepak picture Deepak · Jun 12, 2018 · Viewed 15.1k times · Source

After installing node-config and @types/config:

yarn add config
yarn add --dev @types/config

And 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'.

Answer

Tom Spencer picture Tom Spencer · Apr 20, 2020

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-config without 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