-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvalidator.d.ts
More file actions
122 lines (108 loc) · 2.7 KB
/
validator.d.ts
File metadata and controls
122 lines (108 loc) · 2.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
export type ValidatorFailure<T extends Def> = {
type: T['type']
path: (string | number)[]
value: unknown
}
type Validator<T extends Def> = (
value: unknown,
path?: (string | number)[],
) => ValidatorFailure<T>[]
type DefArray<T extends Def> = {
type: 'array'
of: Def
report: Validator<T>
optional?: boolean
description?: string
assert: (value: unknown) => ReturnType<T['assert']>[]
}
type DefList<T extends readonly (string | number)[]> = {
type: 'list'
of: T
report: Validator<DefList<T>>
optional?: boolean
description?: string
assert: (value: unknown) => T[number]
}
type DefUnion<T extends readonly Def[]> = {
type: 'union'
of: T
report: Validator<DefUnion<T>>
optional?: boolean
description?: string
assert: (value: unknown) => ReturnType<T[number]['assert']>
}
type DefObject<T extends Record<string, Def>> = {
type: 'object'
properties: { [K in keyof T]: T[K] }
report: Validator<T[keyof T]>
optional?: boolean
description?: string
assert: (value: unknown) => { [K in keyof T]: ReturnType<T[K]['assert']> }
}
type DefString = {
type: 'string'
assert: AssertType<string>
report: Validator<DefString>
optional?: boolean
description?: string
}
type DefNumber = {
type: 'number'
assert: AssertType<number>
report: Validator<DefNumber>
optional?: boolean
description?: string
}
type DefBoolean = {
type: 'boolean'
assert: AssertType<boolean>
report: Validator<DefBoolean>
optional?: boolean
description?: string
}
/**
* The base type for all validator definitions.
*/
export type DefBase =
| DefString
| DefNumber
| DefBoolean
// deno-lint-ignore no-explicit-any
| DefList<any>
// deno-lint-ignore no-explicit-any
| DefArray<any>
// deno-lint-ignore no-explicit-any
| DefUnion<any>
// deno-lint-ignore no-explicit-any
| DefObject<Record<string, any>>
export type OptionalAssert<T extends Def['assert']> = (
value: unknown,
) => ReturnType<T> | undefined | null
export type Optional<T extends Def> = T & {
assert: OptionalAssert<T['assert']>
}
type AssertType<T> = (value: unknown) => T
/**
* A validator definition, which can be a base type, an array, an object, or a union.
*/
export type Def<T = unknown> = T extends DefBase ? DefArray<T>
: T extends Record<string, DefBase> ? DefObject<T>
: DefBase
/**
* Infers the asserted type from a validator definition.
*
* @template T - The validator definition.
* @example
* ```ts
* import { OBJ, STR, NUM, type Asserted } from './validator.ts';
*
* const User = OBJ({
* id: NUM(),
* name: STR(),
* });
*
* type UserType = Asserted<typeof User>;
* // { id: number; name: string; }
* ```
*/
export type Asserted<T> = [T] extends [Def] ? ReturnType<T['assert']> : void