json-schema-to-ts
Advanced tools
Comparing version 0.1.3 to 0.1.4
{ | ||
"name": "json-schema-to-ts", | ||
"version": "0.1.3", | ||
"version": "0.1.4", | ||
"description": "Infer typescript types from your JSON schemas!", | ||
@@ -5,0 +5,0 @@ "main": "src/index.ts", |
@@ -5,3 +5,3 @@ # Stop typing twice 🙅♂️ | ||
Their code will probably look like this: | ||
Their code may look like this: | ||
@@ -30,3 +30,3 @@ ```typescript | ||
That's where `json-schema-to-ts` comes to the rescue 💪 | ||
That's when `json-schema-to-ts` comes to the rescue 💪 | ||
@@ -54,2 +54,22 @@ # FromSchema | ||
Schemas can even be nested, as long as you don't forget the `as const` statement: | ||
```typescript | ||
const catSchema = { | ||
type: "object", | ||
properties: { | ||
name: { type: "string" }, | ||
age: { type: "integer" }, | ||
favoriteThings: { enum: ["playing", "sleeping", "sleepingMore"] }, | ||
}, | ||
required: ["name", "age"], | ||
} as const; | ||
const petSchema = { | ||
anyOf: [dogSchema, catSchema], | ||
} as const; | ||
type Pet = FromSchema<typeof petSchema>; // => Will work 🙌 | ||
``` | ||
**Note**: The `as const` statement is used so that TypeScript takes the schema definition to the word (e.g. _true_ is interpreted as the _true_ constant and not as _boolean_). It is pure TypeScript and has zero impact on the compiled code. | ||
@@ -125,6 +145,6 @@ | ||
additionalItems: false, | ||
} | ||
} as const; | ||
type Tuple = FromSchema<typeof tupleSchema>; // => [] | [boolean] | [boolean, string] | ||
const tupleInstance: Tuple = [true, "string", 42] => ❌ | ||
const tupleInstance: Tuple = [true, "string", 42]; // => Will error ❌ | ||
``` | ||
@@ -134,3 +154,3 @@ | ||
``` | ||
```typescript | ||
const fooSchema = { | ||
@@ -145,3 +165,3 @@ const: "foo", | ||
``` | ||
```typescript | ||
const enumSchema = { | ||
@@ -156,3 +176,3 @@ enum: [true, 42, { foo: "bar" }], | ||
``` | ||
```typescript | ||
const enumSchema = { | ||
@@ -167,23 +187,1 @@ type: "string", | ||
If used in concurrency with `const`, the `enum` keyword will be omitted. | ||
### Nested schemas | ||
Nested schemas will work fine as long as you don't forget the `as const` statement! | ||
```typescript | ||
const childSchema = { | ||
type: "object", | ||
properties: { | ||
foo: { type: "string" }, | ||
bar: { type: "integer" }, | ||
}, | ||
required: ["foo", "bar"], | ||
} as const; | ||
const parentSchema = { | ||
type: "array", | ||
items: childSchema, | ||
} as const; | ||
type Parent = FromSchema<typeof parentSchema>; // => Will work 🙌 | ||
``` |
@@ -5,6 +5,6 @@ import { FromWriteableSchema } from "./index"; | ||
? "type" extends keyof S | ||
? S["const"] extends FromWriteableSchema<Omit<S, "const" | "enum">> | ||
? S["const"] extends FromWriteableSchema<Omit<S, "const">> | ||
? S["const"] | ||
: never | ||
: "TypeError: value of const doesn't extend provided type" | ||
: S["const"] | ||
: never; |
@@ -5,9 +5,11 @@ import { FromWriteableSchema } from "./index"; | ||
export type FromEnumSchema<S> = "enum" extends keyof S | ||
? "type" extends keyof S | ||
? RecurseOnEnumSchema<S["enum"], FromWriteableSchema<Omit<S, "enum">>> | ||
: RecurseOnEnumSchema<S["enum"]> | ||
? S["enum"] extends any[] | ||
? Extract<"const" | "type", keyof S> extends never | ||
? RecurseOnEnumSchema<S["enum"]> | ||
: RecurseOnEnumSchema<S["enum"], FromWriteableSchema<Omit<S, "enum">>> | ||
: "TypeError: value of enum should be an array" | ||
: never; | ||
type RecurseOnEnumSchema<S, T = any, R = never> = { | ||
stop: R; | ||
stop: number extends keyof S ? S[number] | R : R; | ||
continue: S extends any[] | ||
@@ -14,0 +16,0 @@ ? Head<S> extends T |
@@ -0,5 +1,6 @@ | ||
import { FromAnyOfSchema } from "./anyOf"; | ||
import { FromEnumSchema } from "./enum"; | ||
import { FromConstSchema } from "./const"; | ||
import { FromObjectSchema } from "./object"; | ||
import { FromArraySchema } from "./array"; | ||
import { FromConstSchema } from "./const"; | ||
import { FromEnumSchema } from "./enum"; | ||
import { Writeable } from "./utils"; | ||
@@ -14,2 +15,5 @@ | ||
never: never; | ||
anyOf: FromAnyOfSchema<S>; | ||
enum: FromEnumSchema<S>; | ||
const: FromConstSchema<S>; | ||
null: null; | ||
@@ -21,4 +25,4 @@ boolean: boolean; | ||
array: FromArraySchema<S>; | ||
const: FromConstSchema<S>; | ||
enum: FromEnumSchema<S>; | ||
structureError: "TypeError: Invalid schema structure"; | ||
typeError: 'TypeError: type value should be "null", "boolean", "integer", "number", "string", "object" or "array"'; | ||
}[InferSchemaType<S>]; | ||
@@ -30,6 +34,8 @@ | ||
? "never" | ||
: "anyOf" extends keyof S | ||
? "anyOf" | ||
: "enum" extends keyof S | ||
? "enum" | ||
: "const" extends keyof S | ||
? "const" | ||
: "enum" extends keyof S | ||
? "enum" | ||
: "type" extends keyof S | ||
@@ -48,3 +54,3 @@ ? S["type"] extends "null" | ||
? "array" | ||
: never | ||
: never; | ||
: "typeError" | ||
: "structureError"; |
@@ -66,3 +66,7 @@ import { Merge } from "./utils"; | ||
export type ConstSchema = MakeSchema<{ | ||
export type AnyOfSchema = MakeSchema<{ | ||
anyOf: any[]; | ||
}>; | ||
export type EnumSchema = MakeSchema<{ | ||
type?: | ||
@@ -76,6 +80,6 @@ | "null" | ||
| "array"; | ||
const: any; | ||
enum: any[]; | ||
}>; | ||
export type EnumSchema = MakeSchema<{ | ||
export type ConstSchema = MakeSchema<{ | ||
type?: | ||
@@ -89,3 +93,3 @@ | "null" | ||
| "array"; | ||
enum: any[]; | ||
const: any; | ||
}>; | ||
@@ -103,3 +107,4 @@ | ||
| ArraySchema | ||
| ConstSchema | ||
| EnumSchema; | ||
| AnyOfSchema | ||
| EnumSchema | ||
| ConstSchema; |
15580
21
316
180