/
tuple.ts
41 lines (36 loc) · 1.19 KB
/
tuple.ts
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
import { createSchema } from '../createSchema';
import { commonCriteria, tupleCriteria } from '../criteria';
import { InferTupleItems } from '../criteria/tuples';
import { createArray, invariant } from '../helpers';
import { CommonCriterias, Criteria, InferNullable, Schema } from '../types';
export interface TupleSchema<T> extends Schema<T>, CommonCriterias<TupleSchema<T>> {
never: () => TupleSchema<never>;
notNullable: () => TupleSchema<NonNullable<T>>;
nullable: () => TupleSchema<T | null>;
/** @internal */
of: <I extends unknown[]>(schemas: InferTupleItems<I>) => TupleSchema<InferNullable<T, I>>;
}
function validateType(): Criteria<unknown[]> | void {
return {
skipIfNull: true,
validate(value, path) {
if (value === undefined) {
// Will be built from its items
return [];
}
invariant(Array.isArray(value), 'Must be a tuple.', path);
return value;
},
};
}
export function tuple<T extends unknown[] = unknown[]>(
schemas: InferTupleItems<T>,
): TupleSchema<T> {
return createSchema<TupleSchema<T>>({
// @ts-expect-error Ignore this, it's safe
cast: createArray,
criteria: { ...commonCriteria, ...tupleCriteria },
type: 'tuple',
validateType,
}).of(schemas);
}