How to use node-config in typescript?

16,238

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

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
Share:
16,238

Related videos on Youtube

Deepak
Author by

Deepak

Updated on September 16, 2022

Comments

  • Deepak
    Deepak over 1 year

    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'.
    
  • Deepak
    Deepak almost 6 years
    It is just a workaround. still looking for better answer.
  • Estus Flask
    Estus Flask almost 6 years
    This is how config is expected to be used. get and has are actual reasons to use it. It provides too much magic to be properly typed. You could extend its type like const 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
    Fedoranimus over 4 years
    Not sure what a "better answer" would look like, but it's important to note that config.get() supports generics. You could do config.get<number>('server.port') and that might be a little cleaner in some instances.
  • Ernest Jones
    Ernest Jones about 2 years
  • Emmanuel Meric de Bellefon
    Emmanuel Meric de Bellefon almost 2 years
    automatic typing could be certainly implemented in the library using ts template litterals