@sinclair/typebox 0.33.22 → 0.34.0
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/build/cjs/compiler/compiler.d.ts +2 -2
- package/build/cjs/compiler/compiler.js +13 -2
- package/build/cjs/errors/errors.js +7 -0
- package/build/cjs/index.d.ts +1 -2
- package/build/cjs/index.js +1 -2
- package/build/cjs/syntax/parse.d.ts +14 -15
- package/build/cjs/syntax/parse.js +6 -5
- package/build/cjs/syntax/runtime.d.ts +17 -4
- package/build/cjs/syntax/runtime.js +180 -27
- package/build/cjs/syntax/static.d.ts +104 -20
- package/build/cjs/type/guard/kind.d.ts +3 -0
- package/build/cjs/type/guard/kind.js +5 -0
- package/build/cjs/type/guard/type.d.ts +3 -0
- package/build/cjs/type/guard/type.js +13 -0
- package/build/cjs/type/index.d.ts +1 -2
- package/build/cjs/type/index.js +1 -2
- package/build/cjs/type/module/index.d.ts +1 -0
- package/build/cjs/type/{strict → module}/index.js +1 -1
- package/build/cjs/type/module/module.d.ts +71 -0
- package/build/cjs/type/module/module.js +34 -0
- package/build/cjs/type/ref/ref.d.ts +4 -7
- package/build/cjs/type/ref/ref.js +3 -11
- package/build/cjs/type/static/static.d.ts +1 -1
- package/build/cjs/type/type/json.d.ts +4 -17
- package/build/cjs/type/type/json.js +52 -68
- package/build/cjs/type/type/type.d.ts +1 -2
- package/build/cjs/type/type/type.js +55 -57
- package/build/cjs/value/cast/cast.js +8 -1
- package/build/cjs/value/check/check.js +8 -1
- package/build/cjs/value/clean/clean.js +8 -1
- package/build/cjs/value/convert/convert.js +7 -0
- package/build/cjs/value/create/create.js +7 -0
- package/build/cjs/value/default/default.js +7 -0
- package/build/cjs/value/transform/decode.js +11 -0
- package/build/cjs/value/transform/encode.js +11 -0
- package/build/esm/compiler/compiler.d.mts +2 -2
- package/build/esm/compiler/compiler.mjs +13 -2
- package/build/esm/errors/errors.mjs +7 -0
- package/build/esm/index.d.mts +1 -2
- package/build/esm/index.mjs +1 -2
- package/build/esm/syntax/parse.d.mts +14 -15
- package/build/esm/syntax/parse.mjs +6 -5
- package/build/esm/syntax/runtime.d.mts +17 -4
- package/build/esm/syntax/runtime.mjs +180 -27
- package/build/esm/syntax/static.d.mts +104 -20
- package/build/esm/type/guard/kind.d.mts +3 -0
- package/build/esm/type/guard/kind.mjs +4 -0
- package/build/esm/type/guard/type.d.mts +3 -0
- package/build/esm/type/guard/type.mjs +12 -0
- package/build/esm/type/index.d.mts +1 -2
- package/build/esm/type/index.mjs +1 -2
- package/build/esm/type/module/index.d.mts +1 -0
- package/build/esm/type/module/index.mjs +1 -0
- package/build/esm/type/module/module.d.mts +71 -0
- package/build/esm/type/module/module.mjs +28 -0
- package/build/esm/type/ref/ref.d.mts +4 -7
- package/build/esm/type/ref/ref.mjs +3 -11
- package/build/esm/type/static/static.d.mts +1 -1
- package/build/esm/type/type/json.d.mts +4 -17
- package/build/esm/type/type/json.mjs +7 -23
- package/build/esm/type/type/type.d.mts +1 -2
- package/build/esm/type/type/type.mjs +1 -2
- package/build/esm/value/cast/cast.mjs +9 -2
- package/build/esm/value/check/check.mjs +9 -2
- package/build/esm/value/clean/clean.mjs +9 -2
- package/build/esm/value/convert/convert.mjs +7 -0
- package/build/esm/value/create/create.mjs +7 -0
- package/build/esm/value/default/default.mjs +7 -0
- package/build/esm/value/transform/decode.mjs +11 -0
- package/build/esm/value/transform/encode.mjs +11 -0
- package/package.json +1 -1
- package/readme.md +219 -97
- package/build/cjs/type/deref/deref.d.ts +0 -22
- package/build/cjs/type/deref/deref.js +0 -106
- package/build/cjs/type/deref/index.d.ts +0 -1
- package/build/cjs/type/deref/index.js +0 -18
- package/build/cjs/type/strict/index.d.ts +0 -1
- package/build/cjs/type/strict/strict.d.ts +0 -12
- package/build/cjs/type/strict/strict.js +0 -16
- package/build/esm/type/deref/deref.d.mts +0 -22
- package/build/esm/type/deref/deref.mjs +0 -102
- package/build/esm/type/deref/index.d.mts +0 -1
- package/build/esm/type/deref/index.mjs +0 -1
- package/build/esm/type/strict/index.d.mts +0 -1
- package/build/esm/type/strict/index.mjs +0 -1
- package/build/esm/type/strict/strict.d.mts +0 -12
- package/build/esm/type/strict/strict.mjs +0 -12
|
@@ -12,7 +12,6 @@ export { Const } from '../const/index.mjs';
|
|
|
12
12
|
export { Constructor } from '../constructor/index.mjs';
|
|
13
13
|
export { ConstructorParameters } from '../constructor-parameters/index.mjs';
|
|
14
14
|
export { Date } from '../date/index.mjs';
|
|
15
|
-
export { Deref } from '../deref/index.mjs';
|
|
16
15
|
export { Enum } from '../enum/index.mjs';
|
|
17
16
|
export { Exclude } from '../exclude/index.mjs';
|
|
18
17
|
export { Extends } from '../extends/index.mjs';
|
|
@@ -27,6 +26,7 @@ export { Iterator } from '../iterator/index.mjs';
|
|
|
27
26
|
export { KeyOf } from '../keyof/index.mjs';
|
|
28
27
|
export { Literal } from '../literal/index.mjs';
|
|
29
28
|
export { Mapped } from '../mapped/index.mjs';
|
|
29
|
+
export { Module } from '../module/index.mjs';
|
|
30
30
|
export { Never } from '../never/index.mjs';
|
|
31
31
|
export { Not } from '../not/index.mjs';
|
|
32
32
|
export { Null } from '../null/index.mjs';
|
|
@@ -48,7 +48,6 @@ export { Required } from '../required/index.mjs';
|
|
|
48
48
|
export { Rest } from '../rest/index.mjs';
|
|
49
49
|
export { ReturnType } from '../return-type/index.mjs';
|
|
50
50
|
export { String } from '../string/index.mjs';
|
|
51
|
-
export { Strict } from '../strict/index.mjs';
|
|
52
51
|
export { Symbol } from '../symbol/index.mjs';
|
|
53
52
|
export { TemplateLiteral } from '../template-literal/index.mjs';
|
|
54
53
|
export { Transform } from '../transform/index.mjs';
|
|
@@ -4,7 +4,7 @@ import { Kind } from '../../type/symbols/index.mjs';
|
|
|
4
4
|
import { Create } from '../create/index.mjs';
|
|
5
5
|
import { Check } from '../check/index.mjs';
|
|
6
6
|
import { Clone } from '../clone/index.mjs';
|
|
7
|
-
import { Deref } from '../deref/index.mjs';
|
|
7
|
+
import { Deref, Pushref } from '../deref/index.mjs';
|
|
8
8
|
// ------------------------------------------------------------------
|
|
9
9
|
// Errors
|
|
10
10
|
// ------------------------------------------------------------------
|
|
@@ -98,6 +98,11 @@ function FromConstructor(schema, references, value) {
|
|
|
98
98
|
}
|
|
99
99
|
return result;
|
|
100
100
|
}
|
|
101
|
+
function FromImport(schema, references, value) {
|
|
102
|
+
const definitions = globalThis.Object.values(schema.$defs);
|
|
103
|
+
const target = schema.$defs[schema.$ref];
|
|
104
|
+
return Visit(target, [...references, ...definitions], value);
|
|
105
|
+
}
|
|
101
106
|
function FromIntersect(schema, references, value) {
|
|
102
107
|
const created = Create(schema, references);
|
|
103
108
|
const mapped = IsObject(created) && IsObject(value) ? { ...created, ...value } : value;
|
|
@@ -161,7 +166,7 @@ function FromUnion(schema, references, value) {
|
|
|
161
166
|
return Check(schema, references, value) ? Clone(value) : CastUnion(schema, references, value);
|
|
162
167
|
}
|
|
163
168
|
function Visit(schema, references, value) {
|
|
164
|
-
const references_ = IsString(schema.$id) ?
|
|
169
|
+
const references_ = IsString(schema.$id) ? Pushref(schema, references) : references;
|
|
165
170
|
const schema_ = schema;
|
|
166
171
|
switch (schema[Kind]) {
|
|
167
172
|
// --------------------------------------------------------------
|
|
@@ -171,6 +176,8 @@ function Visit(schema, references, value) {
|
|
|
171
176
|
return FromArray(schema_, references_, value);
|
|
172
177
|
case 'Constructor':
|
|
173
178
|
return FromConstructor(schema_, references_, value);
|
|
179
|
+
case 'Import':
|
|
180
|
+
return FromImport(schema_, references_, value);
|
|
174
181
|
case 'Intersect':
|
|
175
182
|
return FromIntersect(schema_, references_, value);
|
|
176
183
|
case 'Never':
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { TypeSystemPolicy } from '../../system/index.mjs';
|
|
2
|
-
import { Deref } from '../deref/index.mjs';
|
|
2
|
+
import { Deref, Pushref } from '../deref/index.mjs';
|
|
3
3
|
import { Hash } from '../hash/index.mjs';
|
|
4
4
|
import { Kind } from '../../type/symbols/index.mjs';
|
|
5
5
|
import { KeyOfPattern } from '../../type/keyof/index.mjs';
|
|
@@ -135,6 +135,11 @@ function FromDate(schema, references, value) {
|
|
|
135
135
|
function FromFunction(schema, references, value) {
|
|
136
136
|
return IsFunction(value);
|
|
137
137
|
}
|
|
138
|
+
function FromImport(schema, references, value) {
|
|
139
|
+
const definitions = globalThis.Object.values(schema.$defs);
|
|
140
|
+
const target = schema.$defs[schema.$ref];
|
|
141
|
+
return Visit(target, [...references, ...definitions], value);
|
|
142
|
+
}
|
|
138
143
|
function FromInteger(schema, references, value) {
|
|
139
144
|
if (!IsInteger(value)) {
|
|
140
145
|
return false;
|
|
@@ -380,7 +385,7 @@ function FromKind(schema, references, value) {
|
|
|
380
385
|
return func(schema, value);
|
|
381
386
|
}
|
|
382
387
|
function Visit(schema, references, value) {
|
|
383
|
-
const references_ = IsDefined(schema.$id) ?
|
|
388
|
+
const references_ = IsDefined(schema.$id) ? Pushref(schema, references) : references;
|
|
384
389
|
const schema_ = schema;
|
|
385
390
|
switch (schema_[Kind]) {
|
|
386
391
|
case 'Any':
|
|
@@ -399,6 +404,8 @@ function Visit(schema, references, value) {
|
|
|
399
404
|
return FromDate(schema_, references_, value);
|
|
400
405
|
case 'Function':
|
|
401
406
|
return FromFunction(schema_, references_, value);
|
|
407
|
+
case 'Import':
|
|
408
|
+
return FromImport(schema_, references_, value);
|
|
402
409
|
case 'Integer':
|
|
403
410
|
return FromInteger(schema_, references_, value);
|
|
404
411
|
case 'Intersect':
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { KeyOfPropertyKeys } from '../../type/keyof/index.mjs';
|
|
2
2
|
import { Check } from '../check/index.mjs';
|
|
3
3
|
import { Clone } from '../clone/index.mjs';
|
|
4
|
-
import { Deref } from '../deref/index.mjs';
|
|
4
|
+
import { Deref, Pushref } from '../deref/index.mjs';
|
|
5
5
|
import { Kind } from '../../type/symbols/index.mjs';
|
|
6
6
|
// ------------------------------------------------------------------
|
|
7
7
|
// ValueGuard
|
|
@@ -27,6 +27,11 @@ function FromArray(schema, references, value) {
|
|
|
27
27
|
return value;
|
|
28
28
|
return value.map((value) => Visit(schema.items, references, value));
|
|
29
29
|
}
|
|
30
|
+
function FromImport(schema, references, value) {
|
|
31
|
+
const definitions = globalThis.Object.values(schema.$defs);
|
|
32
|
+
const target = schema.$defs[schema.$ref];
|
|
33
|
+
return Visit(target, [...references, ...definitions], value);
|
|
34
|
+
}
|
|
30
35
|
function FromIntersect(schema, references, value) {
|
|
31
36
|
const unevaluatedProperties = schema.unevaluatedProperties;
|
|
32
37
|
const intersections = schema.allOf.map((schema) => Visit(schema, references, Clone(value)));
|
|
@@ -109,11 +114,13 @@ function FromUnion(schema, references, value) {
|
|
|
109
114
|
return value;
|
|
110
115
|
}
|
|
111
116
|
function Visit(schema, references, value) {
|
|
112
|
-
const references_ = IsString(schema.$id) ?
|
|
117
|
+
const references_ = IsString(schema.$id) ? Pushref(schema, references) : references;
|
|
113
118
|
const schema_ = schema;
|
|
114
119
|
switch (schema_[Kind]) {
|
|
115
120
|
case 'Array':
|
|
116
121
|
return FromArray(schema_, references_, value);
|
|
122
|
+
case 'Import':
|
|
123
|
+
return FromImport(schema_, references_, value);
|
|
117
124
|
case 'Intersect':
|
|
118
125
|
return FromIntersect(schema_, references_, value);
|
|
119
126
|
case 'Object':
|
|
@@ -123,6 +123,11 @@ function FromBoolean(schema, references, value) {
|
|
|
123
123
|
function FromDate(schema, references, value) {
|
|
124
124
|
return TryConvertDate(value);
|
|
125
125
|
}
|
|
126
|
+
function FromImport(schema, references, value) {
|
|
127
|
+
const definitions = globalThis.Object.values(schema.$defs);
|
|
128
|
+
const target = schema.$defs[schema.$ref];
|
|
129
|
+
return Visit(target, [...references, ...definitions], value);
|
|
130
|
+
}
|
|
126
131
|
function FromInteger(schema, references, value) {
|
|
127
132
|
return TryConvertInteger(value);
|
|
128
133
|
}
|
|
@@ -207,6 +212,8 @@ function Visit(schema, references, value) {
|
|
|
207
212
|
return FromBoolean(schema_, references_, value);
|
|
208
213
|
case 'Date':
|
|
209
214
|
return FromDate(schema_, references_, value);
|
|
215
|
+
case 'Import':
|
|
216
|
+
return FromImport(schema_, references_, value);
|
|
210
217
|
case 'Integer':
|
|
211
218
|
return FromInteger(schema_, references_, value);
|
|
212
219
|
case 'Intersect':
|
|
@@ -118,6 +118,11 @@ function FromFunction(schema, references) {
|
|
|
118
118
|
return () => Visit(schema.returns, references);
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
|
+
function FromImport(schema, references) {
|
|
122
|
+
const definitions = globalThis.Object.values(schema.$defs);
|
|
123
|
+
const target = schema.$defs[schema.$ref];
|
|
124
|
+
return Visit(target, [...references, ...definitions]);
|
|
125
|
+
}
|
|
121
126
|
function FromInteger(schema, references) {
|
|
122
127
|
if (HasPropertyKey(schema, 'default')) {
|
|
123
128
|
return FromDefault(schema.default);
|
|
@@ -401,6 +406,8 @@ function Visit(schema, references) {
|
|
|
401
406
|
return FromDate(schema_, references_);
|
|
402
407
|
case 'Function':
|
|
403
408
|
return FromFunction(schema_, references_);
|
|
409
|
+
case 'Import':
|
|
410
|
+
return FromImport(schema_, references_);
|
|
404
411
|
case 'Integer':
|
|
405
412
|
return FromInteger(schema_, references_);
|
|
406
413
|
case 'Intersect':
|
|
@@ -40,6 +40,11 @@ function FromDate(schema, references, value) {
|
|
|
40
40
|
// special case intercept for dates
|
|
41
41
|
return IsDate(value) ? value : ValueOrDefault(schema, value);
|
|
42
42
|
}
|
|
43
|
+
function FromImport(schema, references, value) {
|
|
44
|
+
const definitions = globalThis.Object.values(schema.$defs);
|
|
45
|
+
const target = schema.$defs[schema.$ref];
|
|
46
|
+
return Visit(target, [...references, ...definitions], value);
|
|
47
|
+
}
|
|
43
48
|
function FromIntersect(schema, references, value) {
|
|
44
49
|
const defaulted = ValueOrDefault(schema, value);
|
|
45
50
|
return schema.allOf.reduce((acc, schema) => {
|
|
@@ -133,6 +138,8 @@ function Visit(schema, references, value) {
|
|
|
133
138
|
return FromArray(schema_, references_, value);
|
|
134
139
|
case 'Date':
|
|
135
140
|
return FromDate(schema_, references_, value);
|
|
141
|
+
case 'Import':
|
|
142
|
+
return FromImport(schema_, references_, value);
|
|
136
143
|
case 'Intersect':
|
|
137
144
|
return FromIntersect(schema_, references_, value);
|
|
138
145
|
case 'Object':
|
|
@@ -76,6 +76,15 @@ function FromIntersect(schema, references, path, value) {
|
|
|
76
76
|
}
|
|
77
77
|
return Default(schema, path, unknownProperties);
|
|
78
78
|
}
|
|
79
|
+
// prettier-ignore
|
|
80
|
+
function FromImport(schema, references, path, value) {
|
|
81
|
+
const definitions = globalThis.Object.values(schema.$defs);
|
|
82
|
+
const target = schema.$defs[schema.$ref];
|
|
83
|
+
const transform = schema[TransformKind];
|
|
84
|
+
// Note: we need to re-spec the target as TSchema + [TransformKind]
|
|
85
|
+
const transformTarget = { [TransformKind]: transform, ...target };
|
|
86
|
+
return Visit(transformTarget, [...references, ...definitions], path, value);
|
|
87
|
+
}
|
|
79
88
|
function FromNot(schema, references, path, value) {
|
|
80
89
|
return Default(schema, path, Visit(schema.not, references, path, value));
|
|
81
90
|
}
|
|
@@ -166,6 +175,8 @@ function Visit(schema, references, path, value) {
|
|
|
166
175
|
switch (schema[Kind]) {
|
|
167
176
|
case 'Array':
|
|
168
177
|
return FromArray(schema_, references_, path, value);
|
|
178
|
+
case 'Import':
|
|
179
|
+
return FromImport(schema_, references_, path, value);
|
|
169
180
|
case 'Intersect':
|
|
170
181
|
return FromIntersect(schema_, references_, path, value);
|
|
171
182
|
case 'Not':
|
|
@@ -54,6 +54,15 @@ function FromArray(schema, references, path, value) {
|
|
|
54
54
|
: defaulted;
|
|
55
55
|
}
|
|
56
56
|
// prettier-ignore
|
|
57
|
+
function FromImport(schema, references, path, value) {
|
|
58
|
+
const definitions = globalThis.Object.values(schema.$defs);
|
|
59
|
+
const target = schema.$defs[schema.$ref];
|
|
60
|
+
const transform = schema[TransformKind];
|
|
61
|
+
// Note: we need to re-spec the target as TSchema + [TransformKind]
|
|
62
|
+
const transformTarget = { [TransformKind]: transform, ...target };
|
|
63
|
+
return Visit(transformTarget, [...references, ...definitions], path, value);
|
|
64
|
+
}
|
|
65
|
+
// prettier-ignore
|
|
57
66
|
function FromIntersect(schema, references, path, value) {
|
|
58
67
|
const defaulted = Default(schema, path, value);
|
|
59
68
|
if (!IsObject(value) || IsValueType(value))
|
|
@@ -178,6 +187,8 @@ function Visit(schema, references, path, value) {
|
|
|
178
187
|
switch (schema[Kind]) {
|
|
179
188
|
case 'Array':
|
|
180
189
|
return FromArray(schema_, references_, path, value);
|
|
190
|
+
case 'Import':
|
|
191
|
+
return FromImport(schema_, references_, path, value);
|
|
181
192
|
case 'Intersect':
|
|
182
193
|
return FromIntersect(schema_, references_, path, value);
|
|
183
194
|
case 'Not':
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -68,8 +68,7 @@ License MIT
|
|
|
68
68
|
- [Options](#types-options)
|
|
69
69
|
- [Properties](#types-properties)
|
|
70
70
|
- [Generics](#types-generics)
|
|
71
|
-
- [
|
|
72
|
-
- [Recursive](#types-recursive)
|
|
71
|
+
- [Modules](#types-modules)
|
|
73
72
|
- [Template Literal](#types-template-literal)
|
|
74
73
|
- [Indexed](#types-indexed)
|
|
75
74
|
- [Mapped](#types-mapped)
|
|
@@ -77,6 +76,13 @@ License MIT
|
|
|
77
76
|
- [Transform](#types-transform)
|
|
78
77
|
- [Guard](#types-guard)
|
|
79
78
|
- [Unsafe](#types-unsafe)
|
|
79
|
+
- [Syntax](#syntax)
|
|
80
|
+
- [Parse](#syntax-parse)
|
|
81
|
+
- [Compose](#syntax-compose)
|
|
82
|
+
- [Context](#syntax-context)
|
|
83
|
+
- [Module](#syntax-module)
|
|
84
|
+
- [Static](#syntax-static)
|
|
85
|
+
- [Limits](#syntax-limits)
|
|
80
86
|
- [Values](#values)
|
|
81
87
|
- [Assert](#values-assert)
|
|
82
88
|
- [Create](#values-create)
|
|
@@ -764,103 +770,40 @@ const T = Nullable(Type.String()) // const T = {
|
|
|
764
770
|
type T = Static<typeof T> // type T = string | null
|
|
765
771
|
```
|
|
766
772
|
|
|
767
|
-
<a name='types-
|
|
773
|
+
<a name='types-modules'></a>
|
|
768
774
|
|
|
769
|
-
###
|
|
775
|
+
### Module Types
|
|
770
776
|
|
|
771
|
-
|
|
777
|
+
TypeBox Modules are containers for related types. They function as namespaces and enable internal types to reference each other via string references. Modules support both singular and mutually recursive types. They provide a mechanism to create circular types irrespective of the order in which types are defined.
|
|
772
778
|
|
|
773
779
|
```typescript
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
780
|
+
// The following creates a circular recursive type.
|
|
781
|
+
|
|
782
|
+
const Module = Type.Module({
|
|
783
|
+
A: Type.Object({
|
|
784
|
+
b: Type.Ref('B') // Ref B:
|
|
785
|
+
}),
|
|
786
|
+
B: Type.Object({
|
|
787
|
+
c: Type.Ref('C') // Ref C:
|
|
788
|
+
}),
|
|
789
|
+
C: Type.Object({
|
|
790
|
+
a: Type.Ref('A') // Ref A:
|
|
791
|
+
}),
|
|
792
|
+
})
|
|
783
793
|
|
|
784
|
-
|
|
785
|
-
// $ref: 'Vector'
|
|
786
|
-
// }
|
|
794
|
+
// Module types must be imported before use.
|
|
787
795
|
|
|
788
|
-
|
|
789
|
-
// x: number,
|
|
790
|
-
// y: number
|
|
791
|
-
// }
|
|
792
|
-
```
|
|
793
|
-
Use Deref to dereference a type. This function will replace any interior reference with the target type.
|
|
794
|
-
```typescript
|
|
795
|
-
const Vertex = Type.Object({ // const Vertex = {
|
|
796
|
-
position: VectorRef, // type: 'object',
|
|
797
|
-
texcoord: VectorRef, // required: ['position', 'texcoord'],
|
|
798
|
-
}) // properties: {
|
|
799
|
-
// position: { $ref: 'Vector' },
|
|
800
|
-
// texcoord: { $ref: 'Vector' }
|
|
801
|
-
// }
|
|
802
|
-
// }
|
|
796
|
+
const A = Module.Import('A') // const A: TImport<{...}, 'A'>
|
|
803
797
|
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
// y: { type: 'number' }
|
|
814
|
-
// }
|
|
815
|
-
// },
|
|
816
|
-
// texcoord: {
|
|
817
|
-
// type: 'object',
|
|
818
|
-
// required: ['x', 'y', 'z'],
|
|
819
|
-
// properties: {
|
|
820
|
-
// x: { type: 'number' },
|
|
821
|
-
// y: { type: 'number' }
|
|
822
|
-
// }
|
|
823
|
-
// }
|
|
824
|
-
// }
|
|
825
|
-
// }
|
|
826
|
-
```
|
|
827
|
-
Note that Ref types do not store structural information about the type they're referencing. Because of this, these types cannot be used with some mapping types (such as Partial or Pick). For applications that require mapping on Ref, use Deref to normalize the type first.
|
|
828
|
-
|
|
829
|
-
<a name='types-recursive'></a>
|
|
830
|
-
|
|
831
|
-
### Recursive Types
|
|
832
|
-
|
|
833
|
-
TypeBox supports recursive data structures with Recursive. This type wraps an interior type and provides it a `this` context that allows the type to reference itself. The following creates a recursive type. Singular recursive inference is also supported.
|
|
834
|
-
|
|
835
|
-
```typescript
|
|
836
|
-
const Node = Type.Recursive(This => Type.Object({ // const Node = {
|
|
837
|
-
id: Type.String(), // $id: 'Node',
|
|
838
|
-
nodes: Type.Array(This) // type: 'object',
|
|
839
|
-
}), { $id: 'Node' }) // properties: {
|
|
840
|
-
// id: {
|
|
841
|
-
// type: 'string'
|
|
842
|
-
// },
|
|
843
|
-
// nodes: {
|
|
844
|
-
// type: 'array',
|
|
845
|
-
// items: {
|
|
846
|
-
// $ref: 'Node'
|
|
847
|
-
// }
|
|
848
|
-
// }
|
|
849
|
-
// },
|
|
850
|
-
// required: [
|
|
851
|
-
// 'id',
|
|
852
|
-
// 'nodes'
|
|
853
|
-
// ]
|
|
854
|
-
// }
|
|
855
|
-
|
|
856
|
-
type Node = Static<typeof Node> // type Node = {
|
|
857
|
-
// id: string
|
|
858
|
-
// nodes: Node[]
|
|
859
|
-
// }
|
|
860
|
-
|
|
861
|
-
function test(node: Node) {
|
|
862
|
-
const id = node.nodes[0].nodes[0].id // id is string
|
|
863
|
-
}
|
|
798
|
+
type A = Static<typeof A> // type A = {
|
|
799
|
+
// b: {
|
|
800
|
+
// c: {
|
|
801
|
+
// a: {
|
|
802
|
+
// b: ...
|
|
803
|
+
// }
|
|
804
|
+
// }
|
|
805
|
+
// }
|
|
806
|
+
// }
|
|
864
807
|
```
|
|
865
808
|
|
|
866
809
|
<a name='types-template-literal'></a>
|
|
@@ -1077,6 +1020,185 @@ if(TypeGuard.IsString(T)) {
|
|
|
1077
1020
|
}
|
|
1078
1021
|
```
|
|
1079
1022
|
|
|
1023
|
+
<a name='syntax'></a>
|
|
1024
|
+
|
|
1025
|
+
## Syntax Types
|
|
1026
|
+
|
|
1027
|
+
TypeBox provides support for Syntax Types, enabling it to parse TypeScript syntax directly into TypeBox types. Syntax Types serve as a DSL frontend for TypeBox's type builder and are useful for converting existing TypeScript type definitions into Json Schema schematics.
|
|
1028
|
+
|
|
1029
|
+
Syntax Types are provided via optional import.
|
|
1030
|
+
|
|
1031
|
+
```typescript
|
|
1032
|
+
import { Parse } from '@sinclair/typebox/syntax'
|
|
1033
|
+
```
|
|
1034
|
+
|
|
1035
|
+
<a name='syntax-parse'></a>
|
|
1036
|
+
|
|
1037
|
+
### Parse
|
|
1038
|
+
|
|
1039
|
+
Use the Parse function to convert a TypeScript string into a TypeBox type. TypeBox will infer the appropriate TSchema type or return undefined if there is a syntax error.
|
|
1040
|
+
|
|
1041
|
+
```typescript
|
|
1042
|
+
const A = Parse('string') // const A: TString
|
|
1043
|
+
|
|
1044
|
+
const B = Parse('[1, 2, 3]') // const B: TTuple<[
|
|
1045
|
+
// TLiteral<1>,
|
|
1046
|
+
// TLiteral<2>,
|
|
1047
|
+
// TLiteral<3>
|
|
1048
|
+
// ]>
|
|
1049
|
+
|
|
1050
|
+
const C = Parse(`{ x: number, y: number }`) // const C: TObject<{
|
|
1051
|
+
// x: TNumber
|
|
1052
|
+
// y: TNumber
|
|
1053
|
+
// }>
|
|
1054
|
+
```
|
|
1055
|
+
|
|
1056
|
+
|
|
1057
|
+
|
|
1058
|
+
<a name='syntax-compose'></a>
|
|
1059
|
+
|
|
1060
|
+
### Compose
|
|
1061
|
+
|
|
1062
|
+
Syntax Types are designed to be interchangeable with standard Types.
|
|
1063
|
+
|
|
1064
|
+
```typescript
|
|
1065
|
+
const T = Type.Object({ // const T: TObject<{
|
|
1066
|
+
x: Parse('number'), // x: TNumber,
|
|
1067
|
+
y: Parse('number'), // y: TNumber,
|
|
1068
|
+
z: Parse('number') // z: TNumber
|
|
1069
|
+
}) // }>
|
|
1070
|
+
```
|
|
1071
|
+
|
|
1072
|
+
<a name='syntax-module'></a>
|
|
1073
|
+
|
|
1074
|
+
### Module
|
|
1075
|
+
|
|
1076
|
+
Syntax Types support Module parsing, which is useful for processing multiple TypeScript types. Module parsing supports type alias and interface definitions. Generics are currently unsupported as of 0.34.0.
|
|
1077
|
+
|
|
1078
|
+
```typescript
|
|
1079
|
+
const Foo = Parse(`module Foo {
|
|
1080
|
+
|
|
1081
|
+
export type A = string
|
|
1082
|
+
|
|
1083
|
+
export type B = number
|
|
1084
|
+
|
|
1085
|
+
export type C = A | B
|
|
1086
|
+
|
|
1087
|
+
}`)
|
|
1088
|
+
|
|
1089
|
+
const C = Foo.Import('C') // const C: TImport<{
|
|
1090
|
+
// ...
|
|
1091
|
+
// }, 'C'>
|
|
1092
|
+
```
|
|
1093
|
+
|
|
1094
|
+
<a name='syntax-context'></a>
|
|
1095
|
+
|
|
1096
|
+
### Context
|
|
1097
|
+
|
|
1098
|
+
The Parse function accepts an initial Context argument, allowing external types to be passed into the parser.
|
|
1099
|
+
|
|
1100
|
+
```typescript
|
|
1101
|
+
const T = Type.Object({ // could be written as: Parse(`{
|
|
1102
|
+
x: Type.Number(), // x: number,
|
|
1103
|
+
y: Type.Number(), // y: number,
|
|
1104
|
+
z: Type.Number() // z: number
|
|
1105
|
+
}) // }`)
|
|
1106
|
+
|
|
1107
|
+
const A = Parse({ T }, 'Partial<T>') // const A: TObject<{
|
|
1108
|
+
// x: TOptional<TNumber>,
|
|
1109
|
+
// y: TOptional<TNumber>,
|
|
1110
|
+
// z: TOptional<TNumber>
|
|
1111
|
+
// }>
|
|
1112
|
+
|
|
1113
|
+
const B = Parse({ T }, 'keyof T') // const B: TUnion<[
|
|
1114
|
+
// TLiteral<'x'>,
|
|
1115
|
+
// TLiteral<'y'>,
|
|
1116
|
+
// TLiteral<'z'>
|
|
1117
|
+
// ]>
|
|
1118
|
+
|
|
1119
|
+
const C = Parse({ T }, 'T & { w: number }') // const C: TIntersect<[TObject<{
|
|
1120
|
+
// x: TNumber;
|
|
1121
|
+
// y: TNumber;
|
|
1122
|
+
// z: TNumber;
|
|
1123
|
+
// }>, TObject<{
|
|
1124
|
+
// w: TNumber;
|
|
1125
|
+
// }>]>
|
|
1126
|
+
```
|
|
1127
|
+
|
|
1128
|
+
<a name='syntax-static'></a>
|
|
1129
|
+
|
|
1130
|
+
### Static
|
|
1131
|
+
|
|
1132
|
+
Syntax Types provide two Static types for inferring TypeScript syntax from strings.
|
|
1133
|
+
|
|
1134
|
+
```typescript
|
|
1135
|
+
import { StaticParseAsSchema, StaticParseAsType } from '@sinclair/typebox/syntax'
|
|
1136
|
+
|
|
1137
|
+
// Will infer as a TSchema
|
|
1138
|
+
|
|
1139
|
+
type S = StaticParseAsSchema<{}, '{ x: number }'> // type S: TObject<{
|
|
1140
|
+
// x: TNumber
|
|
1141
|
+
// }>
|
|
1142
|
+
|
|
1143
|
+
// Will infer as a type
|
|
1144
|
+
|
|
1145
|
+
type T = StaticParseAsType<{}, '{ x: number }'> // type T = {
|
|
1146
|
+
// x: number
|
|
1147
|
+
//
|
|
1148
|
+
```
|
|
1149
|
+
|
|
1150
|
+
|
|
1151
|
+
<a name='syntax-limits'></a>
|
|
1152
|
+
|
|
1153
|
+
### Limitations
|
|
1154
|
+
|
|
1155
|
+
Syntax Types work by having TypeBox parse TypeScript syntax within the TypeScript type system. This approach can place some strain on the TypeScript compiler and language service, potentially affecting responsiveness. While TypeBox makes a best-effort attempt to optimize for Syntax Types, users should be mindful of the following structures:
|
|
1156
|
+
|
|
1157
|
+
```typescript
|
|
1158
|
+
// Excessively wide structures will result in instantiation limits exceeding
|
|
1159
|
+
const A = Parse(`[
|
|
1160
|
+
0, 1, 2, 3, 4, 5, 6, 7,
|
|
1161
|
+
0, 1, 2, 3, 4, 5, 6, 7,
|
|
1162
|
+
0, 1, 2, 3, 4, 5, 6, 7,
|
|
1163
|
+
0, 1, 2, 3, 4, 5, 6, 7,
|
|
1164
|
+
0, 1, 2, 3, 4, 5, 6, 7,
|
|
1165
|
+
0, 1, 2, 3, 4, 5, 6, 7,
|
|
1166
|
+
0, 1, 2, 3, 4, 5, 6, 7,
|
|
1167
|
+
0, 1, 2, 3, 4, 5, 6, 7,
|
|
1168
|
+
]`)
|
|
1169
|
+
|
|
1170
|
+
// Excessively nested structures will result in instantiation limits exceeding
|
|
1171
|
+
const B = Parse(`{
|
|
1172
|
+
x: {
|
|
1173
|
+
y: {
|
|
1174
|
+
z: {
|
|
1175
|
+
w: 1 <-- Type instantiation is excessively deep and possibly infinite.
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
}`)
|
|
1180
|
+
```
|
|
1181
|
+
|
|
1182
|
+
In cases where Syntax Types busts through TypeScript instantiation limits, TypeBox offers a fallback ParseOnly function which will Parse the types at runtime, but not infer the type. This function can also be used for parsing non-constant strings.
|
|
1183
|
+
|
|
1184
|
+
```typescript
|
|
1185
|
+
import { ParseOnly } from '@sinclair/typebox/syntax'
|
|
1186
|
+
|
|
1187
|
+
// Where A is TSchema | undefined
|
|
1188
|
+
|
|
1189
|
+
const A = ParseOnly(`{
|
|
1190
|
+
x: {
|
|
1191
|
+
y: {
|
|
1192
|
+
z: {
|
|
1193
|
+
w: 1
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
}`)
|
|
1198
|
+
```
|
|
1199
|
+
|
|
1200
|
+
For more information on TypeBox's parsing infrastructure, refer to the [ParseBox](https://github.com/sinclairzx81/parsebox) project.
|
|
1201
|
+
|
|
1080
1202
|
<a name='values'></a>
|
|
1081
1203
|
|
|
1082
1204
|
## Values
|
|
@@ -1760,12 +1882,12 @@ The following table lists esbuild compiled and minified sizes for each TypeBox m
|
|
|
1760
1882
|
┌──────────────────────┬────────────┬────────────┬─────────────┐
|
|
1761
1883
|
│ (index) │ Compiled │ Minified │ Compression │
|
|
1762
1884
|
├──────────────────────┼────────────┼────────────┼─────────────┤
|
|
1763
|
-
│ typebox/compiler │ '
|
|
1764
|
-
│ typebox/errors │ '
|
|
1765
|
-
│ typebox/
|
|
1885
|
+
│ typebox/compiler │ '121.7 kb' │ ' 53.4 kb' │ '2.28 x' │
|
|
1886
|
+
│ typebox/errors │ ' 75.3 kb' │ ' 33.4 kb' │ '2.25 x' │
|
|
1887
|
+
│ typebox/syntax │ '120.1 kb' │ ' 50.5 kb' │ '2.38 x' │
|
|
1766
1888
|
│ typebox/system │ ' 7.4 kb' │ ' 3.2 kb' │ '2.33 x' │
|
|
1767
|
-
│ typebox/value │ '
|
|
1768
|
-
│ typebox │ '
|
|
1889
|
+
│ typebox/value │ '160.3 kb' │ ' 67.4 kb' │ '2.38 x' │
|
|
1890
|
+
│ typebox │ ' 96.2 kb' │ ' 40.2 kb' │ '2.39 x' │
|
|
1769
1891
|
└──────────────────────┴────────────┴────────────┴─────────────┘
|
|
1770
1892
|
```
|
|
1771
1893
|
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { TSchema } from '../schema/index';
|
|
2
|
-
import type { Evaluate } from '../helpers/index';
|
|
3
|
-
import type { TTuple } from '../tuple/index';
|
|
4
|
-
import type { TIntersect } from '../intersect/index';
|
|
5
|
-
import type { TUnion } from '../union/index';
|
|
6
|
-
import type { TPromise } from '../promise/index';
|
|
7
|
-
import type { TAsyncIterator } from '../async-iterator/index';
|
|
8
|
-
import type { TIterator } from '../iterator/index';
|
|
9
|
-
import type { TArray } from '../array/index';
|
|
10
|
-
import type { TConstructor } from '../constructor/index';
|
|
11
|
-
import type { TFunction } from '../function/index';
|
|
12
|
-
import type { TRef } from '../ref/index';
|
|
13
|
-
import type { TObject, TProperties } from '../object/index';
|
|
14
|
-
export type TFromRest<T extends TSchema[], Acc extends TSchema[] = []> = (T extends [infer L extends TSchema, ...infer R extends TSchema[]] ? TFromRest<R, [...Acc, TDeref<L>]> : Acc);
|
|
15
|
-
type FromProperties<T extends TProperties> = Evaluate<{
|
|
16
|
-
[K in keyof T]: TDeref<T[K]>;
|
|
17
|
-
}>;
|
|
18
|
-
declare function FromProperties(properties: TProperties, references: TSchema[]): never;
|
|
19
|
-
export type TDeref<T extends TSchema> = T extends TConstructor<infer S extends TSchema[], infer R extends TSchema> ? TConstructor<TFromRest<S>, TDeref<R>> : T extends TFunction<infer S extends TSchema[], infer R extends TSchema> ? TFunction<TFromRest<S>, TDeref<R>> : T extends TIntersect<infer S extends TSchema[]> ? TIntersect<TFromRest<S>> : T extends TUnion<infer S extends TSchema[]> ? TUnion<TFromRest<S>> : T extends TTuple<infer S extends TSchema[]> ? TTuple<TFromRest<S>> : T extends TObject<infer S extends TProperties> ? TObject<FromProperties<S>> : T extends TArray<infer S extends TSchema> ? TArray<TDeref<S>> : T extends TPromise<infer S extends TSchema> ? TPromise<TDeref<S>> : T extends TAsyncIterator<infer S extends TSchema> ? TAsyncIterator<TDeref<S>> : T extends TIterator<infer S extends TSchema> ? TIterator<TDeref<S>> : T extends TRef<infer S extends TSchema> ? TDeref<S> : T;
|
|
20
|
-
/** `[Json]` Creates a dereferenced type */
|
|
21
|
-
export declare function Deref<T extends TSchema>(schema: T, references: TSchema[]): TDeref<T>;
|
|
22
|
-
export {};
|