JSPM

  • Created
  • Published
  • Downloads 273
  • Score
    100M100P100Q72076F
  • License GPL-3.0

Infer TypeScript types from JSON schemas

Package Exports

    This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (from-schema) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

    Readme

    from-schema

    Convert JSON schemas to TypeScript types

    Notes

    • Only a small subset of JSONschema is supported
    • This library is very opinionated
    • Probably don't use this in production

    Example - social media post

    // Import various from-schema types
    import { ArraySchema, EnumSchema, FromSchema, ObjectSchema } from 'from-schema';
    
    // Import project-specific models defined elsewhere
    import { attachment } from './attachment';
    import { postBody } from './postBody';
    import { postTitle } from './postTitle';
    import { user } from './user';
    
    // uuid can be passed to AJV for full UUID validation
    export const uuid = {
        type: 'string',
        pattern:
            '^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}$',
    } as const satisfies StringSchema;
    
    // TypeScript will see Uuid as a standard string
    export type Uuid = FromSchema<typeof uuid>;
    /** Equivalent:
     *  type Uuid = string;
     * */
    
    // Define an EnumSchema for the post body type
    export const bodyType = {
        enum: ['plaintext', 'markdown'],
    } as const satisfies EnumSchema;
    
    // Export a type inferred from bodyType
    export type BodyType = FromSchema<typeof bodyType>;
    /** Equivalent:
     *  type BodyType = 'plaintext' | 'markdown'
     * */
    
    // Define an array of attachments (defined elsewhere)
    export const attachments = {
        type: 'array',
        items: attachment,
    } as const satisfies ArraySchema;
    
    // Infer a type based on that model
    export type Attachments = FromSchema<typeof attachments>;
    /* Equivalent:
     *  type Attachments = {<external definition>}[];
     * */
    
    // Define the post itself -- AJV can compile this into a validator
    export const post = {
        description: 'A post containing text, images, or videos',
        type: 'object',
        properties: {
            id: uuid, // You can embed schemas in other schemas
            body: postBody, // Maybe this is a string with specific constraints?
            bodyType,
            groupId: uuid,
            attachments,
            authorId: user.properties.id, // You can model document relationships
            likes: {
                type: 'number',
            },
            publishDate: {
                type: 'string',
            },
            replies: {
                type: 'number',
            },
            title: postTitle, // Another string with constraints defined elsewhere
            thread: {
                type: 'array',
                items: uuid,
            },
        },
        required: [
            'id',
            'authorId',
            'attachments',
            'publishDate',
            'likes',
            'replies',
        ],
    } as const satisfies ObjectSchema;
    
    // Infer a TypeScript type
    export type Post = FromSchema<typeof post>;
    /** Equivalent:
     *  type Post = {
     *    id: string,
     *    body?: string,
     *    bodyType?: 'plaintest' | 'markdown'
     *    groupId?: string,
     *    attachments: {...}[],
     *    authorId: string,
     *    likes: number,
     *    publishDate: string,
     *    replies: number,
     *    title?: string,
     *    thread?: string[]
     *  }
     * */

    Generated documentation

    This section is experimental and may be removed in future.

    ArraySchema

    Defined in ArraySchema.ts.

    export type ArraySchema = SchemaBase & {
        readonly type: 'array';
        readonly items: SchemaOrPrimitive;
        readonly maxLength?: number;
        readonly minLength?: number;
    };

    Represents an array schema. It extends the SchemaBase and has the following properties:

    • type: Must be 'array'.
    • items: The schema or primitive type for the array elements.
    • maxLength (optional): The maximum length of the array.
    • minLength (optional): The minimum length of the array.

    BooleanSchema

    Defined in BooleanSchema.ts.

    export type BooleanSchema = SchemaBase & {
        readonly type: 'boolean';
    };

    Represents a boolean schema. It extends the SchemaBase and has the following property:

    • type: Must be 'boolean'.

    EnumSchemaOf

    Defined in EnumSchemaOf.ts.

    export type EnumSchemaOf<K> = SchemaBase & {
        readonly enum: readonly K[];
    };

    Represents an enumeration schema of a specific type K. It extends the SchemaBase and has the following property:

    • enum: An array of values of type K that the schema can take.

    EnumSchema

    Defined in EnumSchema.ts.

    export type EnumSchema = SchemaBase & {
        readonly enum: readonly (string | number | StringSchema | NumberSchema)[];
    };

    Represents an enumeration schema. It extends the SchemaBase and has the following property:

    • enum: An array of string, number, StringSchema, or NumberSchema values that the schema can take.

    FromObjectSchema

    Defined in FromObjectSchema.ts.

    export type FromObjectSchema<T extends ObjectSchema> = OnlyRequired<T> &
        OnlyOptional<T>;

    A utility type that constructs an object type from an ObjectSchema. It combines the required and optional properties of the schema.

    FromPropertySchemas

    Defined in FromPropertySchemas.ts.

    export type FromPropertySchemas<T extends ObjectSchema> = {
        -readonly [K in keyof T['properties']]: PrimitiveOrFromSchema<
            T['properties'][K]
        >;
    };

    A utility type that constructs an object type from the properties of an ObjectSchema. It maps each property to its primitive or schema type.

    FromSchema

    Defined in FromSchema.ts.

    export type FromSchema<T> = T extends StringSchema
        ? string
        : T extends NumberSchema
            ? number
            : T extends BooleanSchema
                ? boolean
                : T extends UnionSchemaOf<infer P extends SchemaOrPrimitive>
                    ? PrimitiveOrFromSchema<P>
                    : T extends EnumSchemaOf<infer P extends SchemaOrPrimitive>
                        ? PrimitiveOrFromSchema<P>
                        : T extends ObjectSchema
                            ? FromObjectSchema<T>
                            : T extends MapSchema
                                ? FromMapSchema<T>
                                : T extends ArraySchema
                                    ? FromSchema<T['items']>[]
                                    : NoSchema;

    A utility type that constructs a TypeScript type from a schema type. It recursively maps the schema types to their corresponding TypeScript types.

    HttpRoute

    Defined in HttpRoute.ts.

    export type HttpRoute = SchemaBase & {
        readonly request: ObjectSchema;
        readonly response: ObjectSchema;
        readonly authenticated: boolean;
    };

    Represents an HTTP route schema. It extends the SchemaBase and has the following properties:

    • request: An ObjectSchema representing the request schema.
    • response: An ObjectSchema representing the response schema.
    • authenticated: A boolean indicating if authentication is required for the route.

    MapSchema

    Defined in MapSchema.ts.

    export type MapSchema = {
        readonly type: 'map';
        readonly keys: StringSchema | EnumSchemaOf<string>;
        readonly values: Schema;
        readonly partial?: boolean;
    };

    Represents a map schema. It has the following properties:

    • type: Must be 'map'.
    • keys: A StringSchema or EnumSchemaOf<string> representing the schema for the map keys.
    • values: The schema for the map values.
    • partial (optional): A boolean indicating if the map is partial (allows undefined values).

    MapSchemaOf

    Defined in MapSchema.ts.

    export type MapSchemaOf<
        K extends StringSchema | EnumSchemaOf<string>,
        V,
        P = false,
    > = SchemaBase & {
        readonly type: 'map';
        readonly keys: K;
        readonly values: V;
        readonly partial: P;
    };

    Represents a map schema of specific key and value types. It extends the SchemaBase and has the following properties:

    • type: Must be 'map'.
    • keys: The schema for the map keys, of type K.
    • values: The schema or primitive type for the map values, of type V.
    • partial: A boolean indicating if the map is partial (allows undefined values), defaulting to false.

    FromMapSchema

    Defined in MapSchema.ts.

    export type FromMapSchema<S extends MapSchema> = S['partial'] extends true
        ? {
                -readonly [key in S['keys'] extends EnumSchemaOf<infer M extends string>
                    ? M
                    : string]?: FromSchema<S['values']>;
            }
        : {
                -readonly [key in S['keys'] extends EnumSchemaOf<infer M extends string>
                    ? M
                    : string]: FromSchema<S['values']>;
            };

    A utility type that constructs a map type from a MapSchema. It maps the key and value schemas to their corresponding TypeScript types, considering the partial property.

    NumberSchema

    Defined in NumberSchema.ts.

    export type NumberSchema = SchemaBase & {
        readonly type: 'number' | 'integer';
        readonly minimum?: number;
        readonly maximum?: number;
    };

    Represents a number schema. It extends the SchemaBase and has the following properties:

    • type: Must be 'number' or 'integer'.
    • minimum (optional): The minimum value for the number.
    • maximum (optional): The maximum value for the number.

    ObjectSchema

    Defined in ObjectSchema.ts.

    export type ObjectSchemaWithoutRequired = SchemaBase & {
        readonly type: 'object';
        readonly properties: Record<string, SchemaOrPrimitive>;
        readonly minProperties?: number;
        readonly maxProperties?: number;
    };
    
    export type ObjectSchemaWithRequired = ObjectSchemaWithoutRequired & {
        readonly required: readonly string[];
    };
    
    export type ObjectSchema =
        | ObjectSchemaWithoutRequired
        | ObjectSchemaWithRequired;

    Represents an object schema. It extends the SchemaBase and has the following properties:

    • type: Must be 'object'.
    • properties: A record of property names and their corresponding schemas or primitive types.
    • minProperties (optional): The minimum number of properties required in the object.
    • maxProperties (optional): The maximum number of properties allowed in the object.
    • required (optional): An array of required property names.

    OnlyOptional

    Defined in OnlyOptional.ts.

    export type OnlyOptional<T extends ObjectSchema> =
        T extends ObjectSchemaWithRequired
            ? Partial<Omit<FromPropertySchemas<T>, RequiredPropOf<T>>>
            : Partial<T['properties']>;

    A utility type that constructs an object type with only the optional properties of an ObjectSchema.

    OnlyRequired

    Defined in OnlyRequired.ts.

    export type OnlyRequired<T extends ObjectSchema> =
        T extends ObjectSchemaWithRequired
            ? Required<Pick<FromPropertySchemas<T>, RequiredPropOf<T>>>
            : Record<string, never>;

    A utility type that constructs an object type with only the required properties of an ObjectSchema.

    PrimitiveOrFromSchema

    Defined in PrimitiveOrFromSchema.ts.

    export type PrimitiveOrFromSchema<T extends SchemaOrPrimitive> =
        T extends Schema ? FromSchema<T> : T;

    A utility type that constructs a TypeScript type from a schema or primitive type. If the input is a schema, it uses FromSchema to convert it to a TypeScript type; otherwise, it returns the primitive type as is.

    Primitive

    Defined in Primitive.ts.

    export type Primitive = string | number | boolean | string[];

    Represents a primitive type, which can be a string, number, boolean, or an array of strings.

    RequiredPropOf

    Defined in RequiredPropOf.ts.

    export type RequiredPropOf<T extends ObjectSchemaWithRequired> = Extract<
        keyof T['properties'],
        T['required'][number]
    >;

    A utility type that extracts the required property names from an ObjectSchemaWithRequired.

    SchemaBase

    Defined in SchemaBase.ts.

    export type SchemaBase = {
        readonly description?: string;
    };

    Represents the base schema type. It has an optional description property for providing a description of the schema.

    SchemaOrPrimitive

    Defined in SchemaOrPrimitive.ts.

    export type SchemaOrPrimitive = Schema | Primitive;

    Represents a schema or primitive type.

    Schema

    Defined in Schema.ts.

    export type Schema =
        | ArraySchema
        | BooleanSchema
        | EnumSchema
        | MapSchema
        | NumberSchema
        | ObjectSchema
        | StringSchema
        | UnionSchema;

    A union type representing all the available schema types.

    StringSchema

    Defined in StringSchema.ts.

    export type StringSchema = SchemaBase & {
        readonly type: 'string';
        readonly minLength?: number;
        readonly maxLength?: number;
        readonly pattern?: string;
        readonly format?: string;
    };

    Represents a string schema. It extends the SchemaBase and has the following properties:

    • type: Must be 'string'.
    • minLength (optional): The minimum length of the string.
    • maxLength (optional): The maximum length of the string.
    • pattern (optional): A regular expression pattern that the string must match.
    • format (optional): A format specifier for the string (e.g., 'date', 'email').

    UnionSchemaOf

    Defined in UnionSchemaOf.ts.

    export type UnionSchemaOf<K extends SchemaOrPrimitive> = SchemaBase & {
        readonly union: readonly K[];
    };

    Represents a union schema of a specific type K. It extends the SchemaBase and has the following property:

    • union: An array of schemas or primitive types that the schema can take.

    UnionSchema

    Defined in UnionSchema.ts.

    export type UnionSchema = SchemaBase & {
        readonly union: readonly SchemaOrPrimitive[];
    };

    Represents a union schema. It extends the SchemaBase and has the following property:

    • union: An array of schemas or primitive types that the schema can take.

    WebSocketRoute

    Defined in WebSocketRoute.ts.

    export type WebSocketRoute = SchemaBase & Record<string, never>;

    Represents a WebSocket route schema. It extends the SchemaBase and has no additional properties.

    Usage Examples

    Here are some usage examples for the different schema types:

    ArraySchema

    import { ArraySchema } from './ArraySchema';
    
    const myArraySchema: ArraySchema = {
        type: 'array',
        items: {
            type: 'string',
        },
        maxLength: 10,
        minLength: 1,
    };

    BooleanSchema

    import { BooleanSchema } from './BooleanSchema';
    
    const myBooleanSchema: BooleanSchema = {
        type: 'boolean',
    };

    EnumSchema

    import { EnumSchema } from './EnumSchema';
    
    const myEnumSchema: EnumSchema = {
        enum: ['red', 'green', 'blue'],
    };

    MapSchema

    import { MapSchema } from './MapSchema';
    
    const myMapSchema: MapSchema = {
        type: 'map',
        keys: {
            type: 'string',
        },
        values: {
            type: 'number',
        },
        partial: true,
    };

    NumberSchema

    import { NumberSchema } from './NumberSchema';
    
    const myNumberSchema: NumberSchema = {
        type: 'number',
        minimum: 0,
        maximum: 100,
    };

    ObjectSchema

    import { ObjectSchema } from './ObjectSchema';
    
    const myObjectSchema: ObjectSchema = {
        type: 'object',
        properties: {
            name: {
                type: 'string',
            },
            age: {
                type: 'number',
            },
        },
        required: ['name'],
    };

    StringSchema

    import { StringSchema } from './StringSchema';
    
    const myStringSchema: StringSchema = {
        type: 'string',
        minLength: 1,
        maxLength: 50,
        pattern: '^[A-Za-z]+$',
    };

    UnionSchema

    import { UnionSchema } from './UnionSchema';
    
    const myUnionSchema: UnionSchema = {
        union: [
            {
                type: 'string',
            },
            {
                type: 'number',
            },
        ],
    };

    Contribution

    Contributions to this project are welcome. If you find any issues or have suggestions for improvements, please open an issue or submit a pull request on the project's repository.

    License

    This project is licensed under the MIT License.