Validate plain object against TypeScript declaration

I used to find TypeScript comes in handy when we want to validate plain objects against existing TypeScript declarations: such as validating configuration files, data migration results etc. I had written some simple utility functions that basically put generated JSON into a TypeScript file and type check it with the compiler. It works fine but we need more features and a reusable package.

So here comes Tiva, an "expensive" plain object validator leverages TypeScript language service, and it supports extended validation functions.

Usage

It's simple to use:

import {Tiva} from 'tiva';

let tiva = new Tiva();

tiva
  .validate(
    {module: 'module-specifier', type: 'AwesomeType'},
    {foo: 'abc', bar: 123},
  )
  .then(console.info, console.error);

And the ability to extend makes it powerful:

interface Schema {
  /** @uuid */
  id: string;
}

There are several built-in extensions like uuid, unique, pattern. And writing custom extensions is easy:

let tiva = new Tiva({
  extensions: {
    custom(value) {
      if (value === 'custom') {
        return undefined;
      }
      
      return `Value "${value}" must be "custom"`;
    },
  },
});

How it works

Tiva provides a Validator class that manipulates TypeScript language service to do the heavy lifting; and a Tiva class that creates a worker to run Validator in another thread.

The type check part is simple: it just gets the diagnostic messages from TypeScript. The tricky part is the extended validation.

Here's how Tiva does it:

  1. It recursively visits the types used by the type to be validate against.
  2. It find tags like @uuid in those types, and asks TypeScript to find the implementations within the plain object to be validated.
  3. It then validates the value against the extension.

Again the heavy lifting is done by the TypeScript language service. And doing this way also makes it possible to have Tiva work with complex types including condition types, mapping types etc.

Conclusion

Tiva might be a nice tool for certain scenarios, but the way it works makes it "expensive": slow initializing, slow validating, and with a large footprint by any means.

If you find JSON schema related tools insufficient or trivial to setup for your scenarios and performance is not a huge concern, you may want to try out Tiva. But otherwise, I don't think it would be the best choice.