@jakobkg/shapes-ts 0.2.0 → 0.3.1
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 +27 -10
- package/dist/shapes.d.ts +37 -29
- package/dist/shapes.d.ts.map +1 -1
- package/dist/shapes.js +135 -97
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,12 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
Toy library to create runtime safe types in TS.
|
|
4
4
|
|
|
5
|
-
When describing the shape of your data in shapes-ts, you get the corresponding
|
|
5
|
+
When describing the shape of your data in shapes-ts, you get the corresponding
|
|
6
|
+
TS type and a validation utility for free!
|
|
6
7
|
|
|
7
8
|
```typescript
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
const CreditCategory = Shapes.enum(["director", "writer", "actor/actress"])
|
|
10
|
+
|
|
11
|
+
const Credits = Shapes.object({
|
|
12
|
+
category: CreditCategory,
|
|
13
|
+
name: Shapes.string(),
|
|
11
14
|
});
|
|
12
15
|
|
|
13
16
|
const Movie = Shapes.object({
|
|
@@ -16,14 +19,17 @@ const Movie = Shapes.object({
|
|
|
16
19
|
(n) => n >= 0 && n <= 5,
|
|
17
20
|
"rating must be in range 0.0-5.0",
|
|
18
21
|
),
|
|
19
|
-
|
|
22
|
+
credits: Shapes.array(Credits),
|
|
20
23
|
});
|
|
21
24
|
|
|
22
25
|
// This infers as
|
|
23
26
|
// {
|
|
24
27
|
// title: string,
|
|
25
28
|
// rating: number,
|
|
26
|
-
//
|
|
29
|
+
// credits: {
|
|
30
|
+
// category: "director" | "writer" | "actor/actress",
|
|
31
|
+
// name: string
|
|
32
|
+
// }[]
|
|
27
33
|
// }
|
|
28
34
|
type Movie = Shapes.Type<typeof Movie>;
|
|
29
35
|
|
|
@@ -47,19 +53,28 @@ for (const member of movieData.cast) {
|
|
|
47
53
|
- string
|
|
48
54
|
- number
|
|
49
55
|
- boolean
|
|
56
|
+
|
|
57
|
+
...and literals of these
|
|
58
|
+
|
|
59
|
+
### Composite types
|
|
60
|
+
|
|
50
61
|
- object
|
|
51
62
|
- array
|
|
63
|
+
- tuple
|
|
64
|
+
- enum
|
|
52
65
|
|
|
53
66
|
### Modified types
|
|
54
67
|
|
|
55
68
|
- Nullable types (`T | null`)
|
|
56
69
|
- Optional types (`T | undefined`)
|
|
57
|
-
- Unions (`A
|
|
58
|
-
- Intersections (`A
|
|
70
|
+
- Unions (`A | B`)
|
|
71
|
+
- Intersections (`A & B`)
|
|
59
72
|
|
|
60
73
|
## Predicates
|
|
61
74
|
|
|
62
|
-
Shapes can have additional validation checks added to them. These do not affect
|
|
75
|
+
Shapes can have additional validation checks added to them. These do not affect
|
|
76
|
+
the inferred type, but are still ran as part of a shape's `.check()` method to
|
|
77
|
+
help enforce constraints that are not easily modeled using the type system.
|
|
63
78
|
|
|
64
79
|
```typescript
|
|
65
80
|
const Username = Shapes.string().where(
|
|
@@ -71,7 +86,9 @@ Username.check("jakob :)"); // true
|
|
|
71
86
|
Username.check("CptAmericaFan207"); // false
|
|
72
87
|
```
|
|
73
88
|
|
|
74
|
-
Predicates can be used with all types of shapes, and they may be combined both
|
|
89
|
+
Predicates can be used with all types of shapes, and they may be combined both
|
|
90
|
+
by stacking them on a single shape and by combining shapes that already have
|
|
91
|
+
predicates on them.
|
|
75
92
|
|
|
76
93
|
```typescript
|
|
77
94
|
const Fizz = Shapes.number().where(
|
package/dist/shapes.d.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
declare const Predicates: unique symbol;
|
|
2
|
-
declare const Optional: unique symbol;
|
|
3
2
|
declare const Properties: unique symbol;
|
|
4
3
|
declare const AllowUnknownProperties: unique symbol;
|
|
5
4
|
/**
|
|
6
5
|
* Bridge to convert a Shape into a TS type.
|
|
7
6
|
*/
|
|
8
7
|
export type Type<T> = T extends Shape<infer U> ? U : never;
|
|
9
|
-
type ShapePredicate<T> =
|
|
8
|
+
type ShapePredicate<T> = {
|
|
9
|
+
predicate: (x: T) => boolean;
|
|
10
|
+
description: string | undefined;
|
|
11
|
+
};
|
|
10
12
|
interface Shape<T> {
|
|
11
13
|
readonly typename: string;
|
|
12
|
-
readonly [Optional]?: boolean;
|
|
13
14
|
readonly [Predicates]: ShapePredicate<T>[];
|
|
14
15
|
check(x: unknown): x is T;
|
|
15
16
|
/**
|
|
@@ -18,9 +19,9 @@ interface Shape<T> {
|
|
|
18
19
|
* @param description Optional description of the constraint for error messages
|
|
19
20
|
* @returns A new shape with the additional validation
|
|
20
21
|
*/
|
|
21
|
-
where(predicate:
|
|
22
|
-
and<U>(other: Shape<U>):
|
|
23
|
-
or<U>(other: Shape<U>):
|
|
22
|
+
where(predicate: (x: T) => boolean, description: string | undefined): Shape<T>;
|
|
23
|
+
and<U>(other: Shape<U>): Shape<T & U>;
|
|
24
|
+
or<U>(other: Shape<U>): Shape<T | U>;
|
|
24
25
|
}
|
|
25
26
|
interface ObjectShape<T = Record<string, unknown>> extends Shape<T> {
|
|
26
27
|
readonly [Properties]: Record<string, Shape<T>>;
|
|
@@ -30,23 +31,6 @@ interface ObjectShapeOptions {
|
|
|
30
31
|
readonly allowUnknownProperties?: boolean;
|
|
31
32
|
readonly additionalPermittedProperties?: Record<string, Shape<Record<string, unknown>>>;
|
|
32
33
|
}
|
|
33
|
-
interface ArrayShape<T> extends Shape<Array<T>> {
|
|
34
|
-
readonly inner: Shape<T>;
|
|
35
|
-
}
|
|
36
|
-
interface UnionShape<Left, Right> extends Shape<Left | Right> {
|
|
37
|
-
left: Shape<Left>;
|
|
38
|
-
right: Shape<Right>;
|
|
39
|
-
}
|
|
40
|
-
interface IntersectionShape<Left, Right> extends Shape<Left & Right> {
|
|
41
|
-
left: Shape<Left>;
|
|
42
|
-
right: Shape<Right>;
|
|
43
|
-
}
|
|
44
|
-
interface OptionalShape<T> extends Shape<T | undefined> {
|
|
45
|
-
readonly inner: Shape<T>;
|
|
46
|
-
}
|
|
47
|
-
interface NullableShape<T> extends Shape<T | null> {
|
|
48
|
-
readonly inner: Shape<T>;
|
|
49
|
-
}
|
|
50
34
|
/**
|
|
51
35
|
* Creates a shape representing a JS `number`.
|
|
52
36
|
* Does not support BigInt.
|
|
@@ -60,13 +44,21 @@ export declare function string(): Shape<string>;
|
|
|
60
44
|
* Creates a shape representing a JS `boolean`.
|
|
61
45
|
*/
|
|
62
46
|
export declare function boolean(): Shape<boolean>;
|
|
63
|
-
type Primitive = number | string | boolean |
|
|
64
|
-
|
|
47
|
+
type Primitive = number | string | boolean | null | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Creates a shape representing a primitive literal type.
|
|
50
|
+
* Takes numbers, strings, booleans, null and undefined.
|
|
51
|
+
*
|
|
52
|
+
* The resulting shape is equivalent to the type you would
|
|
53
|
+
* get when doing something like `const one = 1 as const;`,
|
|
54
|
+
* where the type is just the literal `1`
|
|
55
|
+
*/
|
|
56
|
+
export declare function literal<T extends Primitive>(x: T): Shape<T>;
|
|
65
57
|
/**
|
|
66
58
|
* Creates an array shape, representing `Array<T>` (aka `T[]`).
|
|
67
59
|
* Takes the shape representing `T` as a parameter.
|
|
68
60
|
*/
|
|
69
|
-
export declare function array<T>(shape: Shape<T>):
|
|
61
|
+
export declare function array<T>(shape: Shape<T>): Shape<T[]>;
|
|
70
62
|
/**
|
|
71
63
|
* Creates an object shape.
|
|
72
64
|
*
|
|
@@ -89,15 +81,31 @@ export declare function array<T>(shape: Shape<T>): ArrayShape<T>;
|
|
|
89
81
|
export declare function object<T extends Record<string, Shape<any>>>(properties: T, options?: ObjectShapeOptions): ObjectShape<{
|
|
90
82
|
[K in keyof T]: Type<T[K]>;
|
|
91
83
|
}>;
|
|
84
|
+
/**
|
|
85
|
+
* Creates a shape representing a tuple type, with an optional rest
|
|
86
|
+
*
|
|
87
|
+
* Shapes.tuple([Shapes.number(), Shape.string()]) is equivalent to TS type [number, string]
|
|
88
|
+
* Shapes.tuple([Shapes.number()], Shapes.string()) is equivalent to TS type [number, ...string]
|
|
89
|
+
*/
|
|
90
|
+
export declare function tuple<Shapes extends Shape<any>[], Partial extends {
|
|
91
|
+
[K in keyof Shapes]: Type<Shapes[K]>;
|
|
92
|
+
}, Tuple extends RestShape extends Shape<infer Rest> ? [...Partial, ...Rest[]] : [...Partial], RestShape extends Shape<any> | undefined = undefined>(shapes: [...Shapes], rest?: RestShape): Shape<Tuple>;
|
|
93
|
+
export { enumOf as enum };
|
|
94
|
+
/**
|
|
95
|
+
* Creates a shape representing an enum type
|
|
96
|
+
* (Not an actual enum as made using the enum keyword)
|
|
97
|
+
*
|
|
98
|
+
* `Shapes.enum(["a", "b", "c"])` is equivalent to `"a" | "b" | "c"`
|
|
99
|
+
*/
|
|
100
|
+
declare function enumOf<T extends (string | number)[]>(values: [...T]): Shape<T[number]>;
|
|
92
101
|
/**
|
|
93
102
|
* Creates a shape representing an optional type.
|
|
94
103
|
* `Shapes.optional(T)` corresponds to `T | undefined`
|
|
95
104
|
*/
|
|
96
|
-
export declare function optional<T>(shape: Shape<T>):
|
|
105
|
+
export declare function optional<T>(shape: Shape<T>): Shape<T | undefined>;
|
|
97
106
|
/**
|
|
98
107
|
* Creates a shape representing a nullable type.
|
|
99
108
|
* `Shapes.nullable(T)` corresponds to `T | null`
|
|
100
109
|
*/
|
|
101
|
-
export declare function nullable<T>(shape: Shape<T>):
|
|
102
|
-
export {};
|
|
110
|
+
export declare function nullable<T>(shape: Shape<T>): Shape<T | null>;
|
|
103
111
|
//# sourceMappingURL=shapes.d.ts.map
|
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,
|
|
1
|
+
{"version":3,"file":"shapes.d.ts","sourceRoot":"","sources":["../src/shapes/shapes.ts"],"names":[],"mappings":"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"}
|
package/dist/shapes.js
CHANGED
|
@@ -26,12 +26,13 @@ exports.boolean = boolean;
|
|
|
26
26
|
exports.literal = literal;
|
|
27
27
|
exports.array = array;
|
|
28
28
|
exports.object = object;
|
|
29
|
+
exports.tuple = tuple;
|
|
30
|
+
exports.enum = enumOf;
|
|
29
31
|
exports.optional = optional;
|
|
30
32
|
exports.nullable = nullable;
|
|
31
33
|
/// SYMBOLS
|
|
32
34
|
// These are here to hide some API bits from consumers
|
|
33
35
|
var Predicates = Symbol();
|
|
34
|
-
var Optional = Symbol();
|
|
35
36
|
var Properties = Symbol();
|
|
36
37
|
var AllowUnknownProperties = Symbol();
|
|
37
38
|
/// TYPE GUARDS
|
|
@@ -49,9 +50,6 @@ function isObject(input) {
|
|
|
49
50
|
function isArray(input) {
|
|
50
51
|
return Array.isArray(input);
|
|
51
52
|
}
|
|
52
|
-
function isNull(input) {
|
|
53
|
-
return input === null;
|
|
54
|
-
}
|
|
55
53
|
function isBoolean(input) {
|
|
56
54
|
return typeof input === "boolean";
|
|
57
55
|
}
|
|
@@ -61,17 +59,16 @@ function isUndefined(input) {
|
|
|
61
59
|
function makeUnion(left, right) {
|
|
62
60
|
var _a;
|
|
63
61
|
return _a = {
|
|
64
|
-
typename: "".concat(left.typename, " | ").concat(right.typename)
|
|
65
|
-
left: left,
|
|
66
|
-
right: right
|
|
62
|
+
typename: "".concat(left.typename, " | ").concat(right.typename)
|
|
67
63
|
},
|
|
68
64
|
_a[Predicates] = [],
|
|
69
|
-
_a.where = function (predicate) {
|
|
70
|
-
|
|
65
|
+
_a.where = function (predicate, description) {
|
|
66
|
+
var _a;
|
|
67
|
+
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [{ predicate: predicate, description: description }], false), _a));
|
|
71
68
|
},
|
|
72
69
|
_a.check = function (x) {
|
|
73
70
|
return (left.check(x) || right.check(x)) &&
|
|
74
|
-
this[Predicates].every(function (p) { return p(x); });
|
|
71
|
+
this[Predicates].every(function (p) { return p.predicate(x); });
|
|
75
72
|
},
|
|
76
73
|
_a.and = function (other) {
|
|
77
74
|
return makeIntersection(this, other);
|
|
@@ -82,20 +79,22 @@ function makeUnion(left, right) {
|
|
|
82
79
|
_a;
|
|
83
80
|
}
|
|
84
81
|
function makeIntersection(left, right) {
|
|
85
|
-
var _a
|
|
82
|
+
var _a;
|
|
86
83
|
return _a = {
|
|
87
|
-
typename: "".concat(left.typename, "
|
|
88
|
-
left: __assign(__assign({}, left), (_b = {}, _b[Properties] = __assign(__assign({}, right[Properties]), left[Properties]), _b)),
|
|
89
|
-
right: __assign(__assign({}, right), (_c = {}, _c[Properties] = __assign(__assign({}, left[Properties]), right[Properties]), _c))
|
|
84
|
+
typename: "".concat(left.typename, " & ").concat(right.typename)
|
|
90
85
|
},
|
|
91
86
|
_a[Predicates] = [],
|
|
92
|
-
_a.where = function (predicate) {
|
|
87
|
+
_a.where = function (predicate, description) {
|
|
93
88
|
var _a;
|
|
94
|
-
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [predicate], false), _a));
|
|
89
|
+
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [{ predicate: predicate, description: description }], false), _a));
|
|
95
90
|
},
|
|
96
91
|
_a.check = function (x) {
|
|
97
|
-
|
|
98
|
-
|
|
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); });
|
|
99
98
|
},
|
|
100
99
|
_a.and = function (other) {
|
|
101
100
|
return makeIntersection(this, other);
|
|
@@ -117,11 +116,11 @@ function number() {
|
|
|
117
116
|
},
|
|
118
117
|
_a[Predicates] = [],
|
|
119
118
|
_a.check = function (x) {
|
|
120
|
-
return isNumber(x) && this[Predicates].every(function (p) { return p(x); });
|
|
119
|
+
return isNumber(x) && this[Predicates].every(function (p) { return p.predicate(x); });
|
|
121
120
|
},
|
|
122
|
-
_a.where = function (predicate) {
|
|
121
|
+
_a.where = function (predicate, description) {
|
|
123
122
|
var _a;
|
|
124
|
-
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [predicate], false), _a));
|
|
123
|
+
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [{ predicate: predicate, description: description }], false), _a));
|
|
125
124
|
},
|
|
126
125
|
_a.and = function (other) {
|
|
127
126
|
return makeIntersection(this, other);
|
|
@@ -139,13 +138,13 @@ function string() {
|
|
|
139
138
|
return _a = {
|
|
140
139
|
typename: "string",
|
|
141
140
|
check: function (x) {
|
|
142
|
-
return isString(x) && this[Predicates].every(function (p) { return p(x); });
|
|
141
|
+
return isString(x) && this[Predicates].every(function (p) { return p.predicate(x); });
|
|
143
142
|
}
|
|
144
143
|
},
|
|
145
144
|
_a[Predicates] = [],
|
|
146
|
-
_a.where = function (predicate) {
|
|
145
|
+
_a.where = function (predicate, description) {
|
|
147
146
|
var _a;
|
|
148
|
-
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [predicate], false), _a));
|
|
147
|
+
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [{ predicate: predicate, description: description }], false), _a));
|
|
149
148
|
},
|
|
150
149
|
_a.and = function (other) {
|
|
151
150
|
return makeIntersection(this, other);
|
|
@@ -163,13 +162,13 @@ function boolean() {
|
|
|
163
162
|
return _a = {
|
|
164
163
|
typename: "boolean",
|
|
165
164
|
check: function (x) {
|
|
166
|
-
return isBoolean(x) && this[Predicates].every(function (p) { return p(x); });
|
|
165
|
+
return isBoolean(x) && this[Predicates].every(function (p) { return p.predicate(x); });
|
|
167
166
|
}
|
|
168
167
|
},
|
|
169
168
|
_a[Predicates] = [],
|
|
170
|
-
_a.where = function (predicate) {
|
|
169
|
+
_a.where = function (predicate, description) {
|
|
171
170
|
var _a;
|
|
172
|
-
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [predicate], false), _a));
|
|
171
|
+
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [{ predicate: predicate, description: description }], false), _a));
|
|
173
172
|
},
|
|
174
173
|
_a.and = function (other) {
|
|
175
174
|
return makeIntersection(this, other);
|
|
@@ -179,18 +178,30 @@ function boolean() {
|
|
|
179
178
|
},
|
|
180
179
|
_a;
|
|
181
180
|
}
|
|
181
|
+
/**
|
|
182
|
+
* Creates a shape representing a primitive literal type.
|
|
183
|
+
* Takes numbers, strings, booleans, null and undefined.
|
|
184
|
+
*
|
|
185
|
+
* The resulting shape is equivalent to the type you would
|
|
186
|
+
* get when doing something like `const one = 1 as const;`,
|
|
187
|
+
* where the type is just the literal `1`
|
|
188
|
+
*/
|
|
182
189
|
function literal(x) {
|
|
183
190
|
var _a;
|
|
191
|
+
function matchesLiteral(u) {
|
|
192
|
+
return u === x;
|
|
193
|
+
}
|
|
184
194
|
return _a = {
|
|
185
|
-
typename: JSON.stringify(x)
|
|
195
|
+
typename: isUndefined(x) ? "undefined" : JSON.stringify(x)
|
|
186
196
|
},
|
|
187
197
|
_a[Predicates] = [],
|
|
188
|
-
_a.check = function (
|
|
189
|
-
return
|
|
198
|
+
_a.check = function (x) {
|
|
199
|
+
return matchesLiteral(x) &&
|
|
200
|
+
this[Predicates].every(function (p) { return p.predicate(x); });
|
|
190
201
|
},
|
|
191
|
-
_a.where = function (predicate) {
|
|
202
|
+
_a.where = function (predicate, description) {
|
|
192
203
|
var _a;
|
|
193
|
-
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [predicate], false), _a));
|
|
204
|
+
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [{ predicate: predicate, description: description }], false), _a));
|
|
194
205
|
},
|
|
195
206
|
_a.and = function (other) {
|
|
196
207
|
return makeIntersection(this, other);
|
|
@@ -210,23 +221,18 @@ function array(shape) {
|
|
|
210
221
|
var typename = "Array<".concat(shape.typename, ">");
|
|
211
222
|
return _a = {
|
|
212
223
|
typename: typename,
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
return false;
|
|
224
|
+
check: function (x) {
|
|
225
|
+
function innerMatches(x) {
|
|
226
|
+
return x.every(function (entry) { return shape.check(entry); });
|
|
217
227
|
}
|
|
218
|
-
return
|
|
219
|
-
|
|
220
|
-
return false;
|
|
221
|
-
}
|
|
222
|
-
return true;
|
|
223
|
-
}) && this[Predicates].every(function (p) { return p(input); });
|
|
228
|
+
return isArray(x) && innerMatches(x) &&
|
|
229
|
+
this[Predicates].every(function (p) { return p.predicate(x); });
|
|
224
230
|
}
|
|
225
231
|
},
|
|
226
232
|
_a[Predicates] = [],
|
|
227
|
-
_a.where = function (predicate) {
|
|
233
|
+
_a.where = function (predicate, description) {
|
|
228
234
|
var _a;
|
|
229
|
-
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [predicate], false), _a));
|
|
235
|
+
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [{ predicate: predicate, description: description }], false), _a));
|
|
230
236
|
},
|
|
231
237
|
_a.and = function (other) {
|
|
232
238
|
return makeIntersection(this, other);
|
|
@@ -258,44 +264,52 @@ function array(shape) {
|
|
|
258
264
|
// deno-lint-ignore no-explicit-any
|
|
259
265
|
function object(properties, options) {
|
|
260
266
|
var _a;
|
|
261
|
-
var
|
|
267
|
+
var _b;
|
|
268
|
+
var allowUnknownProperties = (_b = options === null || options === void 0 ? void 0 : options.allowUnknownProperties) !== null && _b !== void 0 ? _b : false;
|
|
262
269
|
return _a = {
|
|
263
270
|
typename: "Object"
|
|
264
271
|
},
|
|
265
272
|
_a[AllowUnknownProperties] = allowUnknownProperties,
|
|
266
|
-
_a.check = function (
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
// Check for unknown properties
|
|
272
|
-
if (!this[AllowUnknownProperties]) {
|
|
273
|
-
for (var inputProperty in input) {
|
|
274
|
-
if (!(inputProperty in this[Properties])) {
|
|
275
|
-
return false;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
// Check required properties and their types
|
|
280
|
-
for (var property in this[Properties]) {
|
|
281
|
-
var field = input[property];
|
|
282
|
-
var propertyShape = this[Properties][property];
|
|
283
|
-
// Property presence check
|
|
284
|
-
if (!(property in input) && !propertyShape[Optional]) {
|
|
273
|
+
_a.check = function (x) {
|
|
274
|
+
var _this = this;
|
|
275
|
+
var matchesShape = function (input) {
|
|
276
|
+
// Check that input is an object
|
|
277
|
+
if (!isObject(input)) {
|
|
285
278
|
return false;
|
|
286
279
|
}
|
|
287
|
-
//
|
|
288
|
-
if (!
|
|
289
|
-
|
|
280
|
+
// Check for unknown properties
|
|
281
|
+
if (!_this[AllowUnknownProperties]) {
|
|
282
|
+
for (var inputProperty in input) {
|
|
283
|
+
if (!(inputProperty in _this[Properties])) {
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
290
287
|
}
|
|
291
|
-
|
|
292
|
-
|
|
288
|
+
// Check required properties and their types
|
|
289
|
+
for (var property in _this[Properties]) {
|
|
290
|
+
var field = input[property];
|
|
291
|
+
var propertyShape = _this[Properties][property];
|
|
292
|
+
if (isUndefined(propertyShape))
|
|
293
|
+
return false;
|
|
294
|
+
// Property presence check
|
|
295
|
+
if (!(property in input) && !propertyShape.check(undefined)) {
|
|
296
|
+
return false;
|
|
297
|
+
}
|
|
298
|
+
// Property type check
|
|
299
|
+
if (!propertyShape.check(field)) {
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return true;
|
|
304
|
+
};
|
|
305
|
+
return matchesShape(x) &&
|
|
306
|
+
this[Predicates].every(function (p) { return p.predicate(x); });
|
|
293
307
|
},
|
|
294
308
|
_a[Properties] = __assign(__assign({}, properties), options === null || options === void 0 ? void 0 : options.additionalPermittedProperties),
|
|
295
309
|
_a[Predicates] = [],
|
|
296
|
-
_a.where = function (predicate) {
|
|
310
|
+
_a.where = function (predicate, description) {
|
|
297
311
|
var _a;
|
|
298
|
-
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [predicate], false), _a));
|
|
312
|
+
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [{ predicate: predicate, description: description }], false), _a));
|
|
299
313
|
},
|
|
300
314
|
_a.and = function (other) {
|
|
301
315
|
return makeIntersection(this, other);
|
|
@@ -305,26 +319,36 @@ function object(properties, options) {
|
|
|
305
319
|
},
|
|
306
320
|
_a;
|
|
307
321
|
}
|
|
308
|
-
/// TYPE MODIFIERS
|
|
309
322
|
/**
|
|
310
|
-
* Creates a shape representing an optional
|
|
311
|
-
*
|
|
323
|
+
* Creates a shape representing a tuple type, with an optional rest
|
|
324
|
+
*
|
|
325
|
+
* Shapes.tuple([Shapes.number(), Shape.string()]) is equivalent to TS type [number, string]
|
|
326
|
+
* Shapes.tuple([Shapes.number()], Shapes.string()) is equivalent to TS type [number, ...string]
|
|
312
327
|
*/
|
|
313
|
-
function
|
|
328
|
+
function tuple(shapes, rest) {
|
|
314
329
|
var _a;
|
|
330
|
+
var typename = "[".concat(shapes.map(function (s) { return s.typename; }).join(", "), "]");
|
|
315
331
|
return _a = {
|
|
316
|
-
typename:
|
|
317
|
-
inner: shape
|
|
332
|
+
typename: typename
|
|
318
333
|
},
|
|
319
|
-
_a[Optional] = true,
|
|
320
334
|
_a[Predicates] = [],
|
|
321
|
-
_a.check = function (
|
|
322
|
-
|
|
323
|
-
|
|
335
|
+
_a.check = function (x) {
|
|
336
|
+
if (!isArray(x))
|
|
337
|
+
return false;
|
|
338
|
+
if (x.length > shapes.length) {
|
|
339
|
+
// Oversized x and no rest shape can't be valid
|
|
340
|
+
if (rest === undefined)
|
|
341
|
+
return false;
|
|
342
|
+
for (var idx = shapes.length; idx < x.length; idx++) {
|
|
343
|
+
if (!rest.check(x[idx]))
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return shapes.every(function (shape, idx) { return shape.check(x[idx]); }) && this[Predicates].every(function (p) { return p.predicate(x); });
|
|
324
348
|
},
|
|
325
|
-
_a.where = function (predicate) {
|
|
349
|
+
_a.where = function (predicate, description) {
|
|
326
350
|
var _a;
|
|
327
|
-
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [predicate], false), _a));
|
|
351
|
+
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [{ predicate: predicate, description: description }], false), _a));
|
|
328
352
|
},
|
|
329
353
|
_a.and = function (other) {
|
|
330
354
|
return makeIntersection(this, other);
|
|
@@ -335,23 +359,23 @@ function optional(shape) {
|
|
|
335
359
|
_a;
|
|
336
360
|
}
|
|
337
361
|
/**
|
|
338
|
-
* Creates a shape representing
|
|
339
|
-
*
|
|
362
|
+
* Creates a shape representing an enum type
|
|
363
|
+
* (Not an actual enum as made using the enum keyword)
|
|
364
|
+
*
|
|
365
|
+
* `Shapes.enum(["a", "b", "c"])` is equivalent to `"a" | "b" | "c"`
|
|
340
366
|
*/
|
|
341
|
-
function
|
|
367
|
+
function enumOf(values) {
|
|
342
368
|
var _a;
|
|
343
|
-
|
|
344
|
-
typename: "".concat(
|
|
345
|
-
check: function (input) {
|
|
346
|
-
return (isNull(input) || shape.check(input)) &&
|
|
347
|
-
this[Predicates].every(function (p) { return p(input); });
|
|
348
|
-
},
|
|
349
|
-
inner: shape
|
|
369
|
+
return _a = {
|
|
370
|
+
typename: "".concat(values.map(function (v) { return JSON.stringify(v); }).join(" | "))
|
|
350
371
|
},
|
|
351
372
|
_a[Predicates] = [],
|
|
352
|
-
_a.
|
|
373
|
+
_a.check = function (x) {
|
|
374
|
+
return (isNumber(x) || isString(x)) && values.includes(x) && this[Predicates].every(function (p) { return p.predicate(x); });
|
|
375
|
+
},
|
|
376
|
+
_a.where = function (predicate, description) {
|
|
353
377
|
var _a;
|
|
354
|
-
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [predicate], false), _a));
|
|
378
|
+
return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [{ predicate: predicate, description: description }], false), _a));
|
|
355
379
|
},
|
|
356
380
|
_a.and = function (other) {
|
|
357
381
|
return makeIntersection(this, other);
|
|
@@ -359,6 +383,20 @@ function nullable(shape) {
|
|
|
359
383
|
_a.or = function (other) {
|
|
360
384
|
return makeUnion(this, other);
|
|
361
385
|
},
|
|
362
|
-
_a
|
|
363
|
-
|
|
386
|
+
_a;
|
|
387
|
+
}
|
|
388
|
+
/// TYPE MODIFIERS
|
|
389
|
+
/**
|
|
390
|
+
* Creates a shape representing an optional type.
|
|
391
|
+
* `Shapes.optional(T)` corresponds to `T | undefined`
|
|
392
|
+
*/
|
|
393
|
+
function optional(shape) {
|
|
394
|
+
return makeUnion(shape, literal(undefined));
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Creates a shape representing a nullable type.
|
|
398
|
+
* `Shapes.nullable(T)` corresponds to `T | null`
|
|
399
|
+
*/
|
|
400
|
+
function nullable(shape) {
|
|
401
|
+
return makeUnion(shape, literal(null));
|
|
364
402
|
}
|