variable-value-validator
Version:
Minimal schema validation for TypeScript and JavaScript.
76 lines (75 loc) • 3.34 kB
TypeScript
import type { StandardSchemaV1 } from "@standard-schema/spec";
import type { IsLiteralBoolean } from "../../lib/types";
export type SchemaToType<T extends StandardSchemaV1> = StandardSchemaV1.InferOutput<T>;
export interface SchemaOptions<Output = unknown, Optional extends boolean = boolean> {
predicates?: ((data: Output) => boolean) | ((data: Output) => boolean)[];
optional?: Optional;
}
export interface Schema<Output = unknown> extends StandardSchemaV1<Output> {
type: string;
options: SchemaOptions<Output>;
errors: (data: unknown) => ReadonlyArray<StandardSchemaV1.Issue>;
guard: (data: unknown) => data is Output;
}
export interface UnknownSchema extends Schema {
type: "unknown";
}
export interface StringSchema extends Schema<string> {
type: "string";
}
export interface NumberSchema extends Schema<number> {
type: "number";
}
export interface BooleanSchema extends Schema<boolean> {
type: "boolean";
}
export interface UndefinedSchema extends Schema<undefined> {
type: "undefined";
}
export interface NullSchema extends Schema<null> {
type: "null";
}
export interface NullishSchema extends Schema<null | undefined> {
type: "nullish";
}
export interface FunctionSchema extends Schema<(...args: any[]) => any> {
type: "function";
}
export type ObjectConstructor = new (...args: any[]) => Object;
export interface InstanceSchema<Constructor extends ObjectConstructor = ObjectConstructor> extends Schema<InstanceType<Constructor>> {
type: "instance";
constructor: Constructor;
}
export type ObjectShape = {
[key: string]: Schema<any>;
};
export type ObjectShapeToOutput<T extends ObjectShape> = {
[K in keyof T as T[K] extends Schema<any> ? IsLiteralBoolean<T[K]["options"]["optional"]> extends true ? undefined extends T[K]["options"]["optional"] ? K : never : false extends T[K]["options"]["optional"] ? K : never : never]: T[K] extends Schema<any> ? StandardSchemaV1.InferOutput<T[K]> : never;
} & {
[K in keyof T as T[K] extends Schema<any> ? IsLiteralBoolean<T[K]["options"]["optional"]> extends true ? never : true extends T[K]["options"]["optional"] ? K : never : never]?: T[K] extends Schema<any> ? StandardSchemaV1.InferOutput<T[K]> : never;
};
export interface ObjectSchema<Shape extends ObjectShape = ObjectShape> extends Schema<ObjectShapeToOutput<Shape>> {
type: "object";
shape: Shape;
}
export interface ArraySchema<Item extends Schema<any> = Schema<any>> extends Schema<StandardSchemaV1.InferOutput<Item>[]> {
type: "array";
items: Item[];
}
export interface UnionSchema<Member extends Schema<any> = Schema<any>> extends Schema<StandardSchemaV1.InferOutput<Member>> {
type: "union";
members: Member[];
}
export interface RecordSchema<Value extends Schema<any> = Schema<any>> extends Schema<Record<string, StandardSchemaV1.InferOutput<Value>>> {
type: "record";
values: Value[];
}
export interface SetSchema<Value extends Schema<any> = Schema<any>> extends Schema<Set<StandardSchemaV1.InferOutput<Value>>> {
type: "set";
values: Value[];
}
export interface MapSchema<Key extends Schema<any> = Schema<any>, Value extends Schema<any> = Schema<any>> extends Schema<Map<StandardSchemaV1.InferOutput<Key>, StandardSchemaV1.InferOutput<Value>>> {
type: "map";
keys: Key[];
values: Value[];
}