n8jadams
n8jadams

Reputation: 1165

Generate Joi Schema from Typescript types/interfaces

I want to generate some joi schema object from Typescript types or interfaces. In my initial searching I found some things that do the opposite (generate Typescript types/interfaces from joi schemas), and ts-interface-builder + ts-interface-checker that offer some ability to create runtime checkers based on Typescript types/interfaces but were still lacking in feature support, and a whole bunch of gnarly things using classes and decorators around props/methods to accomplish this.

Is there something out there to generate such joi schemas? Or a more mature alternative for runtime checking of interfaces/types? (Useful when pulling from a database and ensuring that the response from a DB is in the correct structure)

EDIT: I guess there's a pretty good thread about this kind of problem on this io-ts github issue.

Upvotes: 11

Views: 10642

Answers (1)

n8jadams
n8jadams

Reputation: 1165

I found something that works to my satisfaction for this: typescript-is.

  1. Swap out what typescript compiler you're using to ttypescript. Instead of calling tsc, call ttsc.
  2. Add the following to tsconfig.json:
{
    "compilerOptions": {
        // Rest of ts config options...
        "plugins": [
            {
                "transform": "typescript-is/lib/transform-inline/transformer"
            }
        ]
    }
}
  1. $ npm install ttypescript typescript-is
  2. Now you can add the following to your code:
import { is, assertType } from 'typescript-is'

interface SomeInterfaceOrType {
    aString: string
}

// To do a simple boolean check, do the following:
const nonConformingObj = { somethingOutOfLeftField: 42 }
const conforms = is<SomeInterfaceOrType>(nonConformingObj) // false

// Or to get better details on what's wrong, do the following
const anotherNonConformer: unknown = { aString: 1337 }
try {
    assertType<SomeInterfaceOrType>(anotherNonConformer)
} catch(error) {
    console.log(error.message) // logs: "validation failed at anotherNonConformer.aString: expected a string"
}

At compile time, the is<T>() and assertType<T>() calls will be transformed into working runtime checks. Not necessarily a JOI schema, but still pretty neat, and definitely good enough for my use case.

Upvotes: 7

Related Questions