Created
July 24, 2023 18:06
-
-
Save bqqbarbhg/cf6a079356bd8ac3db4f924ef38f03a7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| export const fail = Symbol("fail") | |
| export type Fail = typeof fail | |
| export function string(v: any): string | Fail { | |
| return typeof v === "string" ? v : fail | |
| } | |
| export function number(v: any): number | Fail { | |
| return typeof v === "number" ? v : fail | |
| return v | |
| } | |
| export function boolean(v: any): boolean | Fail { | |
| return typeof v === "boolean" ? v : fail | |
| } | |
| type Validator = (a: any) => any | Fail | |
| type ValidatorResult<T extends Validator> = Exclude<ReturnType<T>, Fail> | |
| type ObjectValidator = { | |
| [key: string]: Validator | |
| } | |
| type ObjectResult<T extends ObjectValidator> = { | |
| [key in keyof T]: ValidatorResult<T[key]> | |
| } | Fail | |
| type UnionValidator = { | |
| [key: number]: Validator | |
| } | |
| type UnionResult<T extends UnionValidator> = { | |
| [key in keyof T]: ValidatorResult<T[key]> | |
| }[number] | Fail | |
| export function object<T extends ObjectValidator>(spec: T): ((obj: any) => ObjectResult<T>) { | |
| return (obj: any) => { | |
| const result: any = { } | |
| for (const key of Object.keys(spec)) { | |
| const r = (spec as any)[key]!(obj[key]) | |
| if (r === fail) return fail | |
| result[key] = r | |
| } | |
| return result as ObjectResult<T> | |
| } | |
| } | |
| export function array<T extends Validator>(spec: T): ((obj: any) => ValidatorResult<T>[] | Fail) { | |
| return (obj: any) => { | |
| const result = [] | |
| for (const value of obj) { | |
| const r = spec(value) | |
| if (r === fail) return fail | |
| result.push(r) | |
| } | |
| return result | |
| } | |
| } | |
| export function maybe<T extends Validator>(spec: T): ((obj: any) => ValidatorResult<T> | undefined | Fail) { | |
| return (obj: any) => { | |
| if (obj === undefined) return undefined | |
| return spec(obj) | |
| } | |
| } | |
| export function literal<T extends string | number | boolean>(spec: T): ((obj: any) => T | Fail) { | |
| return (obj: any) => { | |
| if (obj !== spec) return fail | |
| return spec | |
| } | |
| } | |
| export function union<T extends UnionValidator>(spec: T): ((obj: any) => UnionResult<T>) { | |
| return (obj: any) => { | |
| for (const s of (spec as unknown as Validator[])) { | |
| const r = s(obj) | |
| if (r !== fail) return r | |
| } | |
| return fail | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment