json-schema-type-mapper
![npm version](https://badge.fury.io/js/json-schema-type-mapper.svg)
Caution! Experimental software ahead. Use at your own peril.
Type-level conversion of JSON Schema (draft 7) into TypeScript types: handle JSON Schemas as TypeScript types without code generation.
import { Schema } from `json-schema-type-mapper`
declare const myString: Schema<{ type: 'string' }>
Install
yarn add json-schema-type-mapper
Use case
Suppose you're dealing with the following JSON Schema:
interface User {
type: 'object'
properties: {
id: {
type: 'number'
}
name: {
type: 'string'
}
}
required: ['id']
additionalProperties: false
}
And a function whose input conforms to that schema:
function saveUser(user: any) {
}
The question is, how would you define user
parameter's type? There's a couple of ways to go about it. Either
- a) manually write out a TypeScript type definition that matches the above JSON Schema, or
- b) use a code generation tool such as
json-schema-to-typescript
to convert the JSON Schema to a TypeScript interface.
I'd probably go the manual route in a simple case like this and opt for code generation with more complex schemas. This library, however, provides a bit of a middle ground between the two by leveraging the type system:
import { Schema } from 'json-schema-type-mapper'
function saveUser(user: Schema<User>) {
}
Now user
's type resolves to { id: number; name?: string }
. We get automatic conversion from JSON Schema to TypeScript, all by leveraging the type system.
Compared to code generation, this method has a number of limitations resulting from the type system's limitations. We get pretty far though, which in itself is testament to the impressive capabilities of TypeScript's type system.
For a thorough list of supported features and examples check the test file.
Complex example
type User = Schema<{
definitions: {
address: {
$id: '#address'
properties: {
city: { type: 'string' }
country: { type: 'string'; enum: ['FI', 'SV', 'NO'] }
}
required: ['city', 'country']
}
}
allOf: [
{ $ref: '#address' },
{
type: 'object'
properties: {
id: {
anyOf: [
{ type: 'number' },
{ type: 'array'; items: { type: 'number' } }
]
}
name: {
type: ['string', 'null']
}
}
required: ['name']
}
]
}>
type User = {
[x: string]: JSONValue
name: string | null
id?: number | number[] | undefined
city: string
country: "FI" | "SV" | "NO"
}
TODO
Unsupported
Related projects
- as-typed with a similar effort of type-level Schema-to-Typescript conversion
- json-schema-typed provides TypeScript definitions for JSON Schema objects