Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

json-schema-to-ts

Package Overview
Dependencies
Maintainers
1
Versions
81
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

json-schema-to-ts - npm Package Compare versions

Comparing version 0.1.10 to 1.0.0

src/meta-types/any.ts

4

package.json
{
"name": "json-schema-to-ts",
"version": "0.1.10",
"version": "1.0.0",
"description": "Infer typescript types from your JSON schemas!",
"main": "src/index.ts",
"scripts": {
"test": "jest"
"test": "tsc --noEmit && jest --verbose"
},

@@ -9,0 +9,0 @@ "devDependencies": {

@@ -49,3 +49,4 @@ # Stop typing twice 🙅‍♂️

type Dog = FromSchema<typeof dogSchema>; // => Will infer the same type as above
type Dog = FromSchema<typeof dogSchema>;
// => Will infer the same type as above
```

@@ -61,3 +62,3 @@

age: { type: "integer" },
favoriteThings: { enum: ["playing", "sleeping", "sleepingMore"] },
favoriteThings: { enum: ["playing", "sleeping", "moreSleeping"] },
},

@@ -141,4 +142,2 @@ required: ["name", "age"],

You can also specify several types:
```typescript

@@ -153,61 +152,4 @@ const litteralsSchema = {

For `object` and `array` types, properties like `required` or `additionalItems` will also work 🙌
(For `object` and `array` types, properties like `required` or `additionalItems` will work 🙌)
### Objects
```typescript
const objectSchema = {
type: "object",
properties: {
foo: { type: "string" },
bar: { type: "number" },
},
required: ["foo"],
} as const;
type Object = FromSchema<typeof objectSchema>;
// => { foo: string, bar?: number }
```
`FromSchema` partially supports the use of the `additionalProperties` and `patternProperties` keyword:
- Contrary to the specifications, `additionalProperties` is considered `false` by default for clearer typings. Set its value to `true` to signal that additional properties can be used:
```typescript
const additionalPropertiesSchema = {
...objectSchema,
additionalProperties: true,
} as const;
type Object = FromSchema<typeof additionalPropertiesSchema>;
// => { [x: string]: any; foo: string; bar?: number }
```
- Used on their own, typed `additionalProperties` and/or `patternProperties` are supported:
```typescript
const typedValuesSchema = {
type: "object",
additionalProperties: {
type: "boolean",
},
} as const;
type Object = FromSchema<typeof typedValuesSchema>;
// => { [key: string]: boolean }
const patternSchema = {
type: "object",
patternProperties: {
"^S": { type: "string" },
"^I": { type: "integer" },
},
} as const;
type Object = FromSchema<typeof patternSchema>;
// => { [key: string]: string | number }
```
- However, due to [TypeScript limitations](https://github.com/Microsoft/TypeScript/issues/7599), when used in combination with the `properties` keyword, extra properties will always be typed as `any` to avoid conflicts with base properties.
### Arrays

@@ -234,9 +176,7 @@

type Tuple = FromSchema<typeof tupleSchema>;
// => [] | [boolean] | [boolean, string] | [boolean, string, ...any[]]
// => [] | [boolean] | [boolean, string] | [boolean, string, ...unknown[]]
```
`FromSchema` supports the `additionalItems` keyword:
`FromSchema` supports the `additionalItems` specifications:
- You can deny additional items:
```typescript

@@ -253,4 +193,2 @@ const tupleSchema = {

- Or specify a type for additional items:
```typescript

@@ -267,3 +205,3 @@ const tupleSchema = {

`FromSchema` also supports the `minItems` and `maxItems` keyword:
...as well as the `minItems` and `maxItems` specifications:

@@ -282,2 +220,54 @@ ```typescript

(NOTE: Additional items will only work if Typescript's `strictNullChecks` option is activated)
### Objects
```typescript
const objectSchema = {
type: "object",
properties: {
foo: { type: "string" },
bar: { type: "number" },
},
required: ["foo"],
} as const;
type Object = FromSchema<typeof objectSchema>;
// => { [x: string]: unknown; foo: string; bar?: number; }
```
`FromSchema` partially supports the `additionalProperties` and `patternProperties` specifications:
- `additionalProperties` can be used to deny additional items.
```typescript
const closedObjectSchema = {
...objectSchema,
additionalProperties: false,
} as const;
type Object = FromSchema<typeof additionalPropertiesSchema>;
// => { foo: string; bar?: number; }
```
- Used on their own, `additionalProperties` and/or `patternProperties` can be used to type unnamed properties.
```typescript
const objectSchema = {
type: "object",
additionalProperties: {
type: "boolean",
},
patternProperties: {
"^S": { type: "string" },
"^I": { type: "integer" },
},
} as const;
type Object = FromSchema<typeof typedValuesSchema>;
// => { [x: string]: string | number | boolean }
```
- However, when used in combination with the `properties` keyword, extra properties will always be typed as `unknown` to avoid conflicts.
### AnyOf

@@ -299,1 +289,49 @@

```
`FromSchema` will correctly infer factored schemas:
```typescript
const factoredSchema = {
type: "object",
properties: {
bool: { type: "boolean" },
},
required: ["bool"],
anyOf: [
{
properties: {
str: { type: "string" },
},
required: ["str"],
},
{
properties: {
num: { type: "number" },
},
},
],
} as const;
type Factored = FromSchema<typeof factoredSchema>;
// => {
// [x:string]: unknown;
// bool: boolean;
// str: string;
// } | {
// [x:string]: unknown;
// bool: boolean;
// num?: number;
// }
```
### OneOf
...Coming soon 😃
### AllOf
...Coming soon 😃
### If/Else
...Coming soon 😃

@@ -1,7 +0,3 @@

import { FromAnyOfSchema } from "./anyOf";
import { FromEnumSchema } from "./enum";
import { FromConstSchema } from "./const";
import { FromMixedSchema } from "./mixed";
import { FromObjectSchema } from "./object";
import { FromArraySchema } from "./array";
import { Resolve } from "./meta-types";
import { ParseSchema } from "./parse-schema";
import { Writeable } from "./utils";

@@ -12,52 +8,4 @@

*
* Args:
* - `Schema`: JSON schema
* @param S JSON schema
*/
export type FromSchema<S> = FromReadonlySchema<S>;
type FromReadonlySchema<S> = FromWriteableSchema<Writeable<S>>;
export type FromWriteableSchema<S> = {
any: any;
never: never;
anyOf: FromAnyOfSchema<S>;
enum: FromEnumSchema<S>;
const: FromConstSchema<S>;
mixed: FromMixedSchema<S>;
null: null;
boolean: boolean;
number: number;
string: string;
object: FromObjectSchema<S>;
array: FromArraySchema<S>;
structureError: "TypeError: Invalid schema structure";
typeError: "TypeError: Invalid type value. Did you forget to use the 'as const' directive?";
}[InferSchemaType<S>];
type InferSchemaType<S> = S extends true | string
? "any"
: S extends false
? "never"
: "anyOf" extends keyof S
? "anyOf"
: "enum" extends keyof S
? "enum"
: "const" extends keyof S
? "const"
: "type" extends keyof S
? S["type"] extends any[]
? "mixed"
: S["type"] extends "null"
? "null"
: S["type"] extends "boolean"
? "boolean"
: S["type"] extends "integer" | "number"
? "number"
: S["type"] extends "string"
? "string"
: S["type"] extends "object"
? "object"
: S["type"] extends "array"
? "array"
: "typeError"
: "structureError";
export type FromSchema<S> = Resolve<ParseSchema<Writeable<S>>>;

@@ -1,2 +0,2 @@

import { MergeRight } from "./utils";
import { UnsafeMergeRec } from "./utils";

@@ -13,13 +13,16 @@ type CommonProps = {

type MakeSchema<SpecificProps = {}> = MergeRight<CommonProps, SpecificProps>;
type MakeSchema<SpecificProps = {}> = UnsafeMergeRec<
CommonProps,
SpecificProps
>;
export type NullSchema = MakeSchema<{
type NullSchema = MakeSchema<{
type: "null";
}>;
export type BooleanSchema = MakeSchema<{
type BooleanSchema = MakeSchema<{
type: "boolean";
}>;
export type StringSchema = MakeSchema<{
type StringSchema = MakeSchema<{
type: "string";

@@ -32,3 +35,3 @@ maxLength?: number;

export type IntegerSchema = MakeSchema<{
type IntegerSchema = MakeSchema<{
type: "integer";

@@ -42,3 +45,3 @@ multipleOf?: number;

export type NumberSchema = MakeSchema<{
type NumberSchema = MakeSchema<{
type: "number";

@@ -64,3 +67,3 @@ multipleOf?: number;

export type ArraySchema = MakeSchema<{
type ArraySchema = MakeSchema<{
type: "array";

@@ -75,7 +78,7 @@ items?: Schema | any[];

export type AnyOfSchema = MakeSchema<{
type AnyOfSchema = MakeSchema<{
anyOf: any[];
}>;
export type EnumSchema = MakeSchema<{
type ConstSchema = MakeSchema<{
type?:

@@ -89,6 +92,6 @@ | "null"

| "array";
enum: any[];
const: any;
}>;
export type ConstSchema = MakeSchema<{
type EnumSchema = MakeSchema<{
type?:

@@ -102,3 +105,3 @@ | "null"

| "array";
const: any;
enum: any[];
}>;

@@ -105,0 +108,0 @@

import { Head } from "./head";
import { Tail } from "./tail";
import { Prepend } from "./prepend";
import { Reverse } from "./reverse";

@@ -8,11 +9,20 @@ /**

*
* Args:
* - `A`: Tuple `A`
* - `B`: Tuple `B`
* @param A Tuple
* @param B Tuple
* @return Tuple
*/
export type ConcatReversed<A, B extends any[]> = {
stop: B;
continue: A extends any[]
? ConcatReversed<Tail<A>, Prepend<Head<A>, B>>
: never;
continue: ConcatReversed<Tail<A>, Prepend<Head<A>, B>>;
}[A extends [any, ...any[]] ? "continue" : "stop"];
/**
* Concatenate tuple `A` to tuple `B`
*
* @param A Tuple
* @param B Tuple
* @return Tuple
*/
export type Concat<A, B extends any[]> = A extends any[]
? ConcatReversed<Reverse<A>, B>
: never;
/**
* Returns `true` if type `A` extends type `B`, `false` if not
*
* Args:
* - `A`: Type `A`
* - `B`: Type `B`
* @param A Type
* @param B Type
* @return Boolean
*/
export type DoesExtend<A, B> = A extends B ? true : false;
type ArrayKeys = keyof [];
/**
* Returns `true` if both types extend each other, `false` if not
* Returns `true` if type is object, `false` if not (excludes arrays)
*
* Args:
* - `A`: Type `A`
* - `B`: Type `B`
* @param T Type
* @return Boolean
*/
export type DoesBothExtend<A, B> = DoesExtend<A, B> extends true
? DoesExtend<B, A>
export type IsObject<T> = T extends object
? ArrayKeys extends Extract<keyof T, ArrayKeys>
? false
: true
: false;
/**
* Returns `true` if type is array, `false` if not (excludes objects)
*
* @param T Type
* @return Boolean
*/
export type IsArray<T> = T extends object
? ArrayKeys extends Extract<keyof T, ArrayKeys>
? true
: false
: false;

@@ -0,8 +1,17 @@

import { Head } from "./head";
import { Tail } from "./tail";
/**
* Returns the property of an object, `never` if property misses from object
* Returns the property value of an object `O`, `F` if property key misses from object
*
* Args:
* - `Object`: Object
* - `Property`: Property name
* @param O Object
* @param K Property key
* @param F _(optional:_ `never` _)_ Fallback type
* @return Type
*/
export type Get<O, P extends string> = P extends keyof O ? O[P] : never;
export type Get<O, K, F = never> = K extends keyof O ? O[K] : F;
export type GetRec<O, K> = {
continue: GetRec<Get<O, Head<K>>, Tail<K>>;
stop: O;
}[K extends [any, ...any[]] ? "continue" : "stop"];
/**
* Returns the first element of a tuple
* Returns the first element of a tuple `T`
*
* Args:
* - `Tuple`: Tuple
* @param T Tuple
* @return Type
*/
export type Head<T extends any[]> = T[0];
export type Head<T> = T extends any[] ? T[0] : never;

@@ -1,9 +0,12 @@

export { Get } from "./get";
export { And } from "./and";
export { ConcatReversed, Concat } from "./concat";
export { DoesExtend, IsObject, IsArray } from "./extends";
export { FilterExtending } from "./filter";
export { Get, GetRec } from "./get";
export { HasKeyIn } from "./hasKeyIn";
export { Head } from "./head";
export { Tail } from "./tail";
export { SafeMergeRec, UnsafeMergeRec, Merge } from "./merge";
export { Prepend } from "./prepend";
export { Reverse } from "./reverse";
export { ConcatReversed } from "./concat";
export { MergeRight } from "./merge";
export { Tail } from "./tail";
export { Writeable } from "./writeable";
export { DoesExtend, DoesBothExtend } from "./extends";

@@ -0,16 +1,22 @@

import { Concat } from "./concat";
import { IsObject, IsArray } from "./extends";
/**
* Merge two types `A` and `B`:
* - Returns `B` if `A` or `B` is not an object
* Recursively merge two types `A` and `B`:
* - Returns `B` if `A` and `B` are not both objects or arrays
* - Recursively merge `A` and `B` properties if both are objects
* - Concat `A` and `B` if both are arrays
*
* Args:
* - `A`: Type `A`
* - `B`: Type `B`
* `UnsafeMergeRec` preserves non-required properties, but can return `never` if TS infers that `A & B = never` (which can happen if some properties are incompatible)
*
* @param A Type
* @param B Type
* @return Type
*/
export type MergeRight<A, B> = A extends object
? B extends object
export type UnsafeMergeRec<A, B> = IsObject<A> extends true
? IsObject<B> extends true
? {
[K in keyof (A & B)]: K extends keyof B
? K extends keyof A
? MergeRight<A[K], B[K]>
? UnsafeMergeRec<A[K], B[K]>
: B[K]

@@ -22,2 +28,62 @@ : K extends keyof A

: B
: IsArray<A> extends true
? IsArray<B> extends true
? B extends any[]
? Concat<A, B>
: never
: B
: B;
/**
* Recursively merge two types `A` and `B`:
* - Returns `B` if `A` and `B` are not both objects or arrays
* - Recursively merge `A` and `B` properties if both are objects
* - Concat `A` and `B` if both are arrays
*
* Contrary to `UnsafeMergeRec`, `SafeMergeRec` never returns never, but doesn't preserve non-required properties
*
* @param A Type
* @param B Type
* @return Type
*/
export type SafeMergeRec<A, B> = IsObject<A> extends true
? IsObject<B> extends true
? {
[K in keyof A | keyof B]: K extends keyof B
? K extends keyof A
? SafeMergeRec<A[K], B[K]>
: B[K]
: K extends keyof A
? A[K]
: never;
}
: B
: IsArray<A> extends true
? IsArray<B> extends true
? B extends any[]
? Concat<A, B>
: never
: B
: B;
/**
* Merge two types `A` and `B`:
* - Returns `B` if `A` and `B` are not both objects
* - Merge `A` and `B` properties if both are objects
* - Merging is not recursive: Properties of `B` erase properties of `A`
*
* @param A Type
* @param B Type
* @return Type
*/
export type Merge<A, B> = IsObject<A> extends true
? IsObject<B> extends true
? {
[K in keyof A | keyof B]: K extends keyof B
? B[K]
: K extends keyof A
? A[K]
: never;
}
: B
: B;
/**
* Inserts an element at the start of a tuple
*
* Args:
* - `Element`: Element to insert
* - `Tuple`: Tuple
* @param E Element (type)
* @param T Tuple
* @return Tuple
*/

@@ -8,0 +8,0 @@ export type Prepend<E, T extends any[]> = ((

@@ -6,11 +6,10 @@ import { Head } from "./head";

/**
* Reverses a tuple
* Reverses a tuple `T`
*
* Args:
* - `Tuple`: Tuple
* - `Result`: _(optional)_ Reversed tuple
* @param T Tuple
* @return Tuple
*/
export type Reverse<T extends any[], R extends any[] = []> = {
export type Reverse<T, R extends any[] = []> = {
stop: R;
continue: Reverse<Tail<T>, Prepend<Head<T>, R>>;
continue: T extends any[] ? Reverse<Tail<T>, Prepend<Head<T>, R>> : never;
}[T extends [any, ...any[]] ? "continue" : "stop"];
/**
* Remove the first element of a tuple
*
* Args:
* - `Tuple`: Tuple
* @param T Tuple
* @return Tuple
*/
export type Tail<T extends any[]> = ((...args: T) => void) extends (
head: any,
...tail: infer R
) => void
? R
: T;
export type Tail<T> = T extends any[]
? ((...args: T) => void) extends (head: any, ...tail: infer R) => void
? R
: T
: never;
/**
* Recursively remove the `readonly` directive from an object properties
*
* Args:
* - `Object`: Object
* @param O Object
* @return Object
*/

@@ -7,0 +7,0 @@ export type Writeable<O> = O extends object

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc