rc.ts
There's an ungodly amount of similar packages, so I will keep the introduction brief:
rc.ts
is a no-nonsense runtime-configuration loader and validator for TypeScript applications. All you have to do is define a schema for your config and rc.ts
will use it for both compile time and runtime type-safety when it loads a config file.
rc.ts
for you?
Is Pros
- It's fairly un-opinionated.
- It's very lightweight (almost nothing if you are already using io-ts)
- Config schemas are written in a simple, easy-to-understand format.
- Types are enforced at compile time and runtime without needing to duplicate your schema.
- It provides a few helpers that abstract away the complexity of implementing things like schemas with default values.
Cons
- It relies on io-ts, which may be a deal-breaker for some folks, but I would encourage them to give it a chance.
- Since the design is very minimal, only
.json
and.js
config formats are supported (out of the box, at least). Sorry, YAML enthusiasts.
rc.ts
is essentially just a thin wrapper for io-ts
that makes very simple and convenient to do runtime-config validation. If you're used to working with io-ts
directly, this package may not be necessary for you.
Installation
You can install rc.ts
via npm or yarn. You will also need to install the io-ts
peer dependency.
$ npm install rc.ts io-ts
or
$ yarn add rc.ts io-ts
Getting Started
Defining a Schema
schema.ts
; // Don't be swayed by this! It actually integrates with TS very well;
Loading a Config
config.json
your-app.ts
;;; .loadConfigFilepath.resolve'./config.json';
Reaping the Benefits
When you use the above code in your project, the loadConfigFile()
function is able to infer the types from the schema exactly as you would expect it to:
Additionally, if you load a bad config file, a descriptive error will be thrown:
Error: Expecting number at age but instead got: undefined.
More Advanced Use
Alternative Loaders
There are a few other functions that can be used in addition to loadConfigFile()
:
loadConfigObject(data)
This function works just like loadConfigFile()
except that an object is passed rather than a filepath. This could be useful if you wanted to load a YAML file or some other format (using a separate tool) and needed to validate the JS object.
validateConfigObject(data)
Like loadConfigObject()
, this function receives a JS object, but it either returns true
if the data is valid, or an array of strings describing the errors. This could be useful if you need more control over how the errors are handled.
io-ts
Types
Tips on Complex Types
A schema can be much more complex than the basic example shown above. See io-ts for more information on how to define types.
io-ts
Helper Functions for io-ts
is beautiful in many ways, but its functional programming influences can be confusing to newcomers. To help get over some of the hurdles I faced myself, I included a few helper functions for common tasks:
withDefault(type, defaultValue)
This function allows a type to have a fallback value when the input is undefined. This differs from the fallback
function provided by io-ts-types
in that it only falls back if the value is missing, not if it's present but invalid. Here's an example of how to use it:
;; ; ;
With the above schema, the vehicle
value can be omitted and it will default to 'none'
when it is loaded. However, passing 'plane'
will still cause an error to be thrown, because having invalid values silently fallback to defaults (as the fallback
function does) could cause confusion.
Author
Tanner Nielsen tannerntannern@gmail.com
License
MIT