@jakobkg/shapes-ts 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -7
- package/dist/shapes.d.ts +32 -11
- package/dist/shapes.d.ts.map +1 -1
- package/dist/shapes.js +127 -250
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,9 +6,11 @@ When describing the shape of your data in shapes-ts, you get the corresponding
|
|
|
6
6
|
TS type and a validation utility for free!
|
|
7
7
|
|
|
8
8
|
```typescript
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
const CreditCategory = Shapes.enum(["director", "writer", "actor/actress"]);
|
|
10
|
+
|
|
11
|
+
const Credits = Shapes.object({
|
|
12
|
+
category: CreditCategory,
|
|
13
|
+
name: Shapes.string(),
|
|
12
14
|
});
|
|
13
15
|
|
|
14
16
|
const Movie = Shapes.object({
|
|
@@ -17,14 +19,17 @@ const Movie = Shapes.object({
|
|
|
17
19
|
(n) => n >= 0 && n <= 5,
|
|
18
20
|
"rating must be in range 0.0-5.0",
|
|
19
21
|
),
|
|
20
|
-
|
|
22
|
+
credits: Shapes.array(Credits),
|
|
21
23
|
});
|
|
22
24
|
|
|
23
25
|
// This infers as
|
|
24
26
|
// {
|
|
25
27
|
// title: string,
|
|
26
28
|
// rating: number,
|
|
27
|
-
//
|
|
29
|
+
// credits: {
|
|
30
|
+
// category: "director" | "writer" | "actor/actress",
|
|
31
|
+
// name: string
|
|
32
|
+
// }[]
|
|
28
33
|
// }
|
|
29
34
|
type Movie = Shapes.Type<typeof Movie>;
|
|
30
35
|
|
|
@@ -36,8 +41,8 @@ if (!Movie.check(movieData)) {
|
|
|
36
41
|
|
|
37
42
|
// Past this point, movieData is typed as Movie
|
|
38
43
|
|
|
39
|
-
for (const
|
|
40
|
-
console.log(`${
|
|
44
|
+
for (const credit of movieData.credits) {
|
|
45
|
+
console.log(`${credit.name}: ${credit.category}`);
|
|
41
46
|
}
|
|
42
47
|
```
|
|
43
48
|
|
|
@@ -55,6 +60,8 @@ for (const member of movieData.cast) {
|
|
|
55
60
|
|
|
56
61
|
- object
|
|
57
62
|
- array
|
|
63
|
+
- tuple
|
|
64
|
+
- enum
|
|
58
65
|
|
|
59
66
|
### Modified types
|
|
60
67
|
|
package/dist/shapes.d.ts
CHANGED
|
@@ -7,11 +7,13 @@ declare const AllowUnknownProperties: unique symbol;
|
|
|
7
7
|
export type Type<T> = T extends Shape<infer U> ? U : never;
|
|
8
8
|
type ShapePredicate<T> = {
|
|
9
9
|
predicate: (x: T) => boolean;
|
|
10
|
-
description
|
|
10
|
+
description?: string | undefined;
|
|
11
11
|
};
|
|
12
12
|
interface Shape<T> {
|
|
13
13
|
readonly typename: string;
|
|
14
14
|
readonly [Predicates]: ShapePredicate<T>[];
|
|
15
|
+
readonly [Properties]?: Record<string, Shape<T>>;
|
|
16
|
+
readonly [AllowUnknownProperties]?: boolean;
|
|
15
17
|
check(x: unknown): x is T;
|
|
16
18
|
/**
|
|
17
19
|
* Adds a custom validation predicate to the shape
|
|
@@ -19,15 +21,11 @@ interface Shape<T> {
|
|
|
19
21
|
* @param description Optional description of the constraint for error messages
|
|
20
22
|
* @returns A new shape with the additional validation
|
|
21
23
|
*/
|
|
22
|
-
where(predicate: (x: T) => boolean, description
|
|
24
|
+
where(predicate: (x: T) => boolean, description?: string | undefined): Shape<T>;
|
|
23
25
|
and<U>(other: Shape<U>): Shape<T & U>;
|
|
24
26
|
or<U>(other: Shape<U>): Shape<T | U>;
|
|
25
27
|
}
|
|
26
|
-
interface
|
|
27
|
-
readonly [Properties]: Record<string, Shape<T>>;
|
|
28
|
-
readonly [AllowUnknownProperties]?: boolean;
|
|
29
|
-
}
|
|
30
|
-
interface ObjectShapeOptions {
|
|
28
|
+
interface ObjectOptions {
|
|
31
29
|
readonly allowUnknownProperties?: boolean;
|
|
32
30
|
readonly additionalPermittedProperties?: Record<string, Shape<Record<string, unknown>>>;
|
|
33
31
|
}
|
|
@@ -45,6 +43,14 @@ export declare function string(): Shape<string>;
|
|
|
45
43
|
*/
|
|
46
44
|
export declare function boolean(): Shape<boolean>;
|
|
47
45
|
type Primitive = number | string | boolean | null | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Creates a shape representing a primitive literal type.
|
|
48
|
+
* Takes numbers, strings, booleans, null and undefined.
|
|
49
|
+
*
|
|
50
|
+
* The resulting shape is equivalent to the type you would
|
|
51
|
+
* get when doing something like `const one = 1 as const;`,
|
|
52
|
+
* where the type is just the literal `1`
|
|
53
|
+
*/
|
|
48
54
|
export declare function literal<T extends Primitive>(x: T): Shape<T>;
|
|
49
55
|
/**
|
|
50
56
|
* Creates an array shape, representing `Array<T>` (aka `T[]`).
|
|
@@ -70,14 +76,29 @@ export declare function array<T>(shape: Shape<T>): Shape<T[]>;
|
|
|
70
76
|
* });
|
|
71
77
|
* ```
|
|
72
78
|
*/
|
|
73
|
-
export declare function object<T extends Record<string, Shape<any>>>(properties: T, options?:
|
|
79
|
+
export declare function object<T extends Record<string, Shape<any>>>(typename: string, properties: T, options?: ObjectOptions | undefined): Shape<{
|
|
80
|
+
[K in keyof T]: Type<T[K]>;
|
|
81
|
+
}>;
|
|
82
|
+
export declare function object<T extends Record<string, Shape<any>>>(properties: T, options?: ObjectOptions | undefined): Shape<{
|
|
74
83
|
[K in keyof T]: Type<T[K]>;
|
|
75
84
|
}>;
|
|
76
|
-
|
|
85
|
+
/**
|
|
86
|
+
* Creates a shape representing a tuple type, with an optional rest
|
|
87
|
+
*
|
|
88
|
+
* Shapes.tuple([Shapes.number(), Shape.string()]) is equivalent to TS type [number, string]
|
|
89
|
+
* Shapes.tuple([Shapes.number()], Shapes.string()) is equivalent to TS type [number, ...string]
|
|
90
|
+
*/
|
|
91
|
+
export declare function tuple<Shapes extends Shape<any>[], Elements extends {
|
|
77
92
|
[K in keyof Shapes]: Type<Shapes[K]>;
|
|
78
|
-
}, Tuple extends RestShape extends Shape<infer Rest> ? [...
|
|
93
|
+
}, Tuple extends RestShape extends Shape<infer Rest> ? [...Elements, ...Rest[]] : [...Elements], RestShape extends Shape<any> | undefined = undefined>(shapes: [...Shapes], rest?: RestShape): Shape<Tuple>;
|
|
79
94
|
export { enumOf as enum };
|
|
80
|
-
|
|
95
|
+
/**
|
|
96
|
+
* Creates a shape representing an enum type.
|
|
97
|
+
* (Not an actual enum as made using the enum keyword)
|
|
98
|
+
*
|
|
99
|
+
* `Shapes.enum(["a", "b", "c"])` is equivalent to `"a" | "b" | "c"`
|
|
100
|
+
*/
|
|
101
|
+
declare function enumOf<T extends (string | number)[]>(values: [...T]): Shape<T[number]>;
|
|
81
102
|
/**
|
|
82
103
|
* Creates a shape representing an optional type.
|
|
83
104
|
* `Shapes.optional(T)` corresponds to `T | undefined`
|
package/dist/shapes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shapes.d.ts","sourceRoot":"","sources":["../src/shapes/shapes.ts"],"names":[],"mappings":"AAEA,QAAA,MAAM,UAAU,eAAW,CAAC;AAC5B,QAAA,MAAM,UAAU,eAAW,CAAC;AAC5B,QAAA,MAAM,sBAAsB,eAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"shapes.d.ts","sourceRoot":"","sources":["../src/shapes/shapes.ts"],"names":[],"mappings":"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"}
|
package/dist/shapes.js
CHANGED
|
@@ -56,46 +56,34 @@ function isBoolean(input) {
|
|
|
56
56
|
function isUndefined(input) {
|
|
57
57
|
return input === undefined;
|
|
58
58
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
return
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
_a.check = function (x) {
|
|
70
|
-
return (left.check(x) || right.check(x)) &&
|
|
71
|
-
this[Predicates].every(function (p) { return p.predicate(x); });
|
|
72
|
-
},
|
|
73
|
-
_a.and = function (other) {
|
|
74
|
-
return makeIntersection(this, other);
|
|
75
|
-
},
|
|
76
|
-
_a.or = function (other) {
|
|
77
|
-
return makeUnion(this, other);
|
|
78
|
-
},
|
|
79
|
-
_a;
|
|
59
|
+
/// HELLA UTILS
|
|
60
|
+
function tryPredicates(self, input) {
|
|
61
|
+
return self[Predicates].every(function (p) {
|
|
62
|
+
try {
|
|
63
|
+
return p.predicate(input);
|
|
64
|
+
}
|
|
65
|
+
catch (_) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
80
69
|
}
|
|
81
|
-
|
|
70
|
+
/// PRIMITIVE SHAPE FACTORIES
|
|
71
|
+
/**
|
|
72
|
+
* Creates a base object that implements the most basic shared logic for all shapes
|
|
73
|
+
*
|
|
74
|
+
* `.typename` and `.check(x)` on the returned object are stubs and should be overwritten
|
|
75
|
+
*/
|
|
76
|
+
function base() {
|
|
82
77
|
var _a;
|
|
83
78
|
return _a = {
|
|
84
|
-
typename: ""
|
|
79
|
+
typename: "",
|
|
80
|
+
check: function (_) { return false; }
|
|
85
81
|
},
|
|
86
82
|
_a[Predicates] = [],
|
|
87
83
|
_a.where = function (predicate, description) {
|
|
88
84
|
var _a;
|
|
89
85
|
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [{ predicate: predicate, description: description }], false), _a));
|
|
90
86
|
},
|
|
91
|
-
_a.check = function (x) {
|
|
92
|
-
var _a, _b;
|
|
93
|
-
// Trickery: combine permitted properties of left and right
|
|
94
|
-
var tolerantLeft = __assign(__assign({}, left), (_a = {}, _a[Properties] = __assign(__assign({}, right[Properties]), left[Properties]), _a));
|
|
95
|
-
var tolerantRight = __assign(__assign({}, right), (_b = {}, _b[Properties] = __assign(__assign({}, left[Properties]), right[Properties]), _b));
|
|
96
|
-
return tolerantLeft.check(x) && tolerantRight.check(x) &&
|
|
97
|
-
this[Predicates].every(function (p) { return p.predicate(x); });
|
|
98
|
-
},
|
|
99
87
|
_a.and = function (other) {
|
|
100
88
|
return makeIntersection(this, other);
|
|
101
89
|
},
|
|
@@ -104,269 +92,158 @@ function makeIntersection(left, right) {
|
|
|
104
92
|
},
|
|
105
93
|
_a;
|
|
106
94
|
}
|
|
107
|
-
|
|
95
|
+
function makePrimitive(name, guard) {
|
|
96
|
+
return __assign(__assign({}, base()), { typename: name, check: function (x) {
|
|
97
|
+
return guard(x) && tryPredicates(this, x);
|
|
98
|
+
} });
|
|
99
|
+
}
|
|
108
100
|
/**
|
|
109
101
|
* Creates a shape representing a JS `number`.
|
|
110
102
|
* Does not support BigInt.
|
|
111
103
|
*/
|
|
112
104
|
function number() {
|
|
113
|
-
|
|
114
|
-
return _a = {
|
|
115
|
-
typename: "number"
|
|
116
|
-
},
|
|
117
|
-
_a[Predicates] = [],
|
|
118
|
-
_a.check = function (x) {
|
|
119
|
-
return isNumber(x) && this[Predicates].every(function (p) { return p.predicate(x); });
|
|
120
|
-
},
|
|
121
|
-
_a.where = function (predicate, description) {
|
|
122
|
-
var _a;
|
|
123
|
-
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [{ predicate: predicate, description: description }], false), _a));
|
|
124
|
-
},
|
|
125
|
-
_a.and = function (other) {
|
|
126
|
-
return makeIntersection(this, other);
|
|
127
|
-
},
|
|
128
|
-
_a.or = function (other) {
|
|
129
|
-
return makeUnion(this, other);
|
|
130
|
-
},
|
|
131
|
-
_a;
|
|
105
|
+
return makePrimitive("number", isNumber);
|
|
132
106
|
}
|
|
133
107
|
/**
|
|
134
108
|
* Creates a shape representing a JS `string`.
|
|
135
109
|
*/
|
|
136
110
|
function string() {
|
|
137
|
-
|
|
138
|
-
return _a = {
|
|
139
|
-
typename: "string",
|
|
140
|
-
check: function (x) {
|
|
141
|
-
return isString(x) && this[Predicates].every(function (p) { return p.predicate(x); });
|
|
142
|
-
}
|
|
143
|
-
},
|
|
144
|
-
_a[Predicates] = [],
|
|
145
|
-
_a.where = function (predicate, description) {
|
|
146
|
-
var _a;
|
|
147
|
-
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [{ predicate: predicate, description: description }], false), _a));
|
|
148
|
-
},
|
|
149
|
-
_a.and = function (other) {
|
|
150
|
-
return makeIntersection(this, other);
|
|
151
|
-
},
|
|
152
|
-
_a.or = function (other) {
|
|
153
|
-
return makeUnion(this, other);
|
|
154
|
-
},
|
|
155
|
-
_a;
|
|
111
|
+
return makePrimitive("string", isString);
|
|
156
112
|
}
|
|
157
113
|
/**
|
|
158
114
|
* Creates a shape representing a JS `boolean`.
|
|
159
115
|
*/
|
|
160
116
|
function boolean() {
|
|
161
|
-
|
|
162
|
-
return _a = {
|
|
163
|
-
typename: "boolean",
|
|
164
|
-
check: function (x) {
|
|
165
|
-
return isBoolean(x) && this[Predicates].every(function (p) { return p.predicate(x); });
|
|
166
|
-
}
|
|
167
|
-
},
|
|
168
|
-
_a[Predicates] = [],
|
|
169
|
-
_a.where = function (predicate, description) {
|
|
170
|
-
var _a;
|
|
171
|
-
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [{ predicate: predicate, description: description }], false), _a));
|
|
172
|
-
},
|
|
173
|
-
_a.and = function (other) {
|
|
174
|
-
return makeIntersection(this, other);
|
|
175
|
-
},
|
|
176
|
-
_a.or = function (other) {
|
|
177
|
-
return makeUnion(this, other);
|
|
178
|
-
},
|
|
179
|
-
_a;
|
|
117
|
+
return makePrimitive("boolean", isBoolean);
|
|
180
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Creates a shape representing a primitive literal type.
|
|
121
|
+
* Takes numbers, strings, booleans, null and undefined.
|
|
122
|
+
*
|
|
123
|
+
* The resulting shape is equivalent to the type you would
|
|
124
|
+
* get when doing something like `const one = 1 as const;`,
|
|
125
|
+
* where the type is just the literal `1`
|
|
126
|
+
*/
|
|
181
127
|
function literal(x) {
|
|
182
|
-
var _a;
|
|
183
128
|
function matchesLiteral(u) {
|
|
184
129
|
return u === x;
|
|
185
130
|
}
|
|
186
|
-
return
|
|
187
|
-
|
|
188
|
-
}
|
|
189
|
-
_a[Predicates] = [],
|
|
190
|
-
_a.check = function (input) {
|
|
191
|
-
return matchesLiteral(input) &&
|
|
192
|
-
this[Predicates].every(function (p) { return p.predicate(input); });
|
|
193
|
-
},
|
|
194
|
-
_a.where = function (predicate, description) {
|
|
195
|
-
var _a;
|
|
196
|
-
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [{ predicate: predicate, description: description }], false), _a));
|
|
197
|
-
},
|
|
198
|
-
_a.and = function (other) {
|
|
199
|
-
return makeIntersection(this, other);
|
|
200
|
-
},
|
|
201
|
-
_a.or = function (other) {
|
|
202
|
-
return makeUnion(this, other);
|
|
203
|
-
},
|
|
204
|
-
_a;
|
|
131
|
+
return __assign(__assign({}, base()), { typename: isUndefined(x) ? "undefined" : JSON.stringify(x), check: function (x) {
|
|
132
|
+
return matchesLiteral(x) && tryPredicates(this, x);
|
|
133
|
+
} });
|
|
205
134
|
}
|
|
206
135
|
/// COMPLEX SHAPE FACTORIES
|
|
136
|
+
function makeUnion(left, right) {
|
|
137
|
+
return __assign(__assign({}, base()), { typename: "".concat(left.typename, " | ").concat(right.typename), check: function (x) {
|
|
138
|
+
return (left.check(x) || right.check(x)) && tryPredicates(this, x);
|
|
139
|
+
} });
|
|
140
|
+
}
|
|
141
|
+
function makeIntersection(left, right) {
|
|
142
|
+
var _a, _b, _c;
|
|
143
|
+
// Trickery: combine permitted properties of left and right shape
|
|
144
|
+
var tolerantLeft = __assign(__assign({}, left), (_a = {}, _a[AllowUnknownProperties] = true, _a));
|
|
145
|
+
var tolerantRight = __assign(__assign({}, right), (_b = {}, _b[AllowUnknownProperties] = true, _b));
|
|
146
|
+
return __assign(__assign({}, base()), (_c = { typename: "".concat(left.typename, " & ").concat(right.typename) }, _c[Properties] = __assign(__assign({}, left[Properties]), right[Properties]), _c.check = function (x) {
|
|
147
|
+
return tolerantLeft.check(x) && tolerantRight.check(x) && tryPredicates(this, x);
|
|
148
|
+
}, _c));
|
|
149
|
+
}
|
|
207
150
|
/**
|
|
208
151
|
* Creates an array shape, representing `Array<T>` (aka `T[]`).
|
|
209
152
|
* Takes the shape representing `T` as a parameter.
|
|
210
153
|
*/
|
|
211
154
|
function array(shape) {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
return x.every(function (entry) { return shape.check(entry); });
|
|
219
|
-
}
|
|
220
|
-
return isArray(input) && innerMatches(input) &&
|
|
221
|
-
this[Predicates].every(function (p) { return p.predicate(input); });
|
|
222
|
-
}
|
|
223
|
-
},
|
|
224
|
-
_a[Predicates] = [],
|
|
225
|
-
_a.where = function (predicate, description) {
|
|
226
|
-
var _a;
|
|
227
|
-
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [{ predicate: predicate, description: description }], false), _a));
|
|
228
|
-
},
|
|
229
|
-
_a.and = function (other) {
|
|
230
|
-
return makeIntersection(this, other);
|
|
231
|
-
},
|
|
232
|
-
_a.or = function (other) {
|
|
233
|
-
return makeUnion(this, other);
|
|
234
|
-
},
|
|
235
|
-
_a;
|
|
155
|
+
function innerMatches(x) {
|
|
156
|
+
return x.every(function (entry) { return shape.check(entry); });
|
|
157
|
+
}
|
|
158
|
+
return __assign(__assign({}, base()), { typename: "Array<".concat(shape.typename, ">"), check: function (x) {
|
|
159
|
+
return isArray(x) && innerMatches(x) && tryPredicates(this, x);
|
|
160
|
+
} });
|
|
236
161
|
}
|
|
237
|
-
/**
|
|
238
|
-
* Creates an object shape.
|
|
239
|
-
*
|
|
240
|
-
* @example
|
|
241
|
-
* ```typescript
|
|
242
|
-
* const Group = Shapes.object({
|
|
243
|
-
* id: Shapes.number(),
|
|
244
|
-
* name: Shapes.string(),
|
|
245
|
-
* });
|
|
246
|
-
*
|
|
247
|
-
* const User = Shapes.object({
|
|
248
|
-
* id: Shapes.number(),
|
|
249
|
-
* name: Shapes.string(),
|
|
250
|
-
* groups: Shapes.nullable(
|
|
251
|
-
* Shapes.array(Group)
|
|
252
|
-
* )
|
|
253
|
-
* });
|
|
254
|
-
* ```
|
|
255
|
-
*/
|
|
256
162
|
// deno-lint-ignore no-explicit-any
|
|
257
|
-
function object(
|
|
163
|
+
function object(nameOrProperties, propertiesOrOptions, maybeOptions) {
|
|
258
164
|
var _a;
|
|
259
165
|
var _b;
|
|
166
|
+
var typename;
|
|
167
|
+
var properties;
|
|
168
|
+
var options;
|
|
169
|
+
if (typeof nameOrProperties === "string") {
|
|
170
|
+
typename = nameOrProperties;
|
|
171
|
+
properties = propertiesOrOptions;
|
|
172
|
+
options = maybeOptions;
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
properties = nameOrProperties;
|
|
176
|
+
options = propertiesOrOptions;
|
|
177
|
+
}
|
|
260
178
|
var allowUnknownProperties = (_b = options === null || options === void 0 ? void 0 : options.allowUnknownProperties) !== null && _b !== void 0 ? _b : false;
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
179
|
+
function matchesShape(self, input) {
|
|
180
|
+
// Check that input is an object
|
|
181
|
+
if (!isObject(input)) {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
if (self[Properties] === undefined)
|
|
185
|
+
return false;
|
|
186
|
+
// Check for unknown properties
|
|
187
|
+
if (!self[AllowUnknownProperties]) {
|
|
188
|
+
for (var inputProperty in input) {
|
|
189
|
+
if (!(inputProperty in self[Properties])) {
|
|
270
190
|
return false;
|
|
271
191
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
}
|
|
295
|
-
return true;
|
|
296
|
-
};
|
|
297
|
-
return matchesShape(input) &&
|
|
298
|
-
this[Predicates].every(function (p) { return p.predicate(input); });
|
|
299
|
-
},
|
|
300
|
-
_a[Properties] = __assign(__assign({}, properties), options === null || options === void 0 ? void 0 : options.additionalPermittedProperties),
|
|
301
|
-
_a[Predicates] = [],
|
|
302
|
-
_a.where = function (predicate, description) {
|
|
303
|
-
var _a;
|
|
304
|
-
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [{ predicate: predicate, description: description }], false), _a));
|
|
305
|
-
},
|
|
306
|
-
_a.and = function (other) {
|
|
307
|
-
return makeIntersection(this, other);
|
|
308
|
-
},
|
|
309
|
-
_a.or = function (other) {
|
|
310
|
-
return makeUnion(this, other);
|
|
311
|
-
},
|
|
312
|
-
_a;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// Check required properties and their types
|
|
195
|
+
for (var property in self[Properties]) {
|
|
196
|
+
var field = input[property];
|
|
197
|
+
var propertyShape = self[Properties][property];
|
|
198
|
+
if (isUndefined(propertyShape))
|
|
199
|
+
return false;
|
|
200
|
+
// Property presence check
|
|
201
|
+
if (!(property in input) && !propertyShape.check(undefined)) {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
// Property type check
|
|
205
|
+
if (!propertyShape.check(field)) {
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
return __assign(__assign({}, base()), (_a = { typename: typename !== null && typename !== void 0 ? typename : "object" }, _a[AllowUnknownProperties] = allowUnknownProperties, _a.check = function (x) {
|
|
212
|
+
return matchesShape(this, x) && tryPredicates(this, x);
|
|
213
|
+
}, _a[Properties] = __assign(__assign({}, properties), options === null || options === void 0 ? void 0 : options.additionalPermittedProperties), _a));
|
|
313
214
|
}
|
|
215
|
+
/**
|
|
216
|
+
* Creates a shape representing a tuple type, with an optional rest
|
|
217
|
+
*
|
|
218
|
+
* Shapes.tuple([Shapes.number(), Shape.string()]) is equivalent to TS type [number, string]
|
|
219
|
+
* Shapes.tuple([Shapes.number()], Shapes.string()) is equivalent to TS type [number, ...string]
|
|
220
|
+
*/
|
|
314
221
|
function tuple(shapes, rest) {
|
|
315
|
-
|
|
316
|
-
var typename = "[".concat(shapes.map(function (s) { return s.typename; }).join(", "), "]");
|
|
317
|
-
return _a = {
|
|
318
|
-
typename: typename
|
|
319
|
-
},
|
|
320
|
-
_a[Predicates] = [],
|
|
321
|
-
_a.check = function (x) {
|
|
222
|
+
return __assign(__assign({}, base()), { typename: "[".concat(shapes.map(function (s) { return s.typename; }).join(", ")).concat(rest === undefined ? "" : ", ...".concat(rest.typename, "[]"), "]"), check: function (x) {
|
|
322
223
|
if (!isArray(x))
|
|
323
224
|
return false;
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
225
|
+
if (x.length > shapes.length) {
|
|
226
|
+
// Oversized x and no rest shape can't be valid
|
|
227
|
+
if (rest === undefined)
|
|
228
|
+
return false;
|
|
327
229
|
for (var idx = shapes.length; idx < x.length; idx++) {
|
|
328
230
|
if (!rest.check(x[idx]))
|
|
329
231
|
return false;
|
|
330
232
|
}
|
|
331
233
|
}
|
|
332
|
-
return shapes.every(function (shape, idx) { return shape.check(x[idx]); });
|
|
333
|
-
}
|
|
334
|
-
_a.where = function (predicate, description) {
|
|
335
|
-
var _a;
|
|
336
|
-
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [{ predicate: predicate, description: description }], false), _a));
|
|
337
|
-
},
|
|
338
|
-
_a.and = function (other) {
|
|
339
|
-
return makeIntersection(this, other);
|
|
340
|
-
},
|
|
341
|
-
_a.or = function (other) {
|
|
342
|
-
return makeUnion(this, other);
|
|
343
|
-
},
|
|
344
|
-
_a;
|
|
234
|
+
return shapes.every(function (shape, idx) { return shape.check(x[idx]); }) && tryPredicates(this, x);
|
|
235
|
+
} });
|
|
345
236
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
_a.check = function (x) {
|
|
357
|
-
return (isNumber(x) || isString(x)) && values.includes(x);
|
|
358
|
-
},
|
|
359
|
-
_a.where = function (predicate, description) {
|
|
360
|
-
var _a;
|
|
361
|
-
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [{ predicate: predicate, description: description }], false), _a));
|
|
362
|
-
},
|
|
363
|
-
_a.and = function (other) {
|
|
364
|
-
return makeIntersection(this, other);
|
|
365
|
-
},
|
|
366
|
-
_a.or = function (other) {
|
|
367
|
-
return makeUnion(this, other);
|
|
368
|
-
},
|
|
369
|
-
_a;
|
|
237
|
+
/**
|
|
238
|
+
* Creates a shape representing an enum type.
|
|
239
|
+
* (Not an actual enum as made using the enum keyword)
|
|
240
|
+
*
|
|
241
|
+
* `Shapes.enum(["a", "b", "c"])` is equivalent to `"a" | "b" | "c"`
|
|
242
|
+
*/
|
|
243
|
+
function enumOf(values) {
|
|
244
|
+
return __assign(__assign({}, base()), { typename: "".concat(values.map(function (v) { return JSON.stringify(v); }).join(" | ")), check: function (x) {
|
|
245
|
+
return (isNumber(x) || isString(x)) && values.includes(x) && tryPredicates(this, x);
|
|
246
|
+
} });
|
|
370
247
|
}
|
|
371
248
|
/// TYPE MODIFIERS
|
|
372
249
|
/**
|