@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.
Files changed (87) hide show
  1. package/build/cjs/compiler/compiler.d.ts +2 -2
  2. package/build/cjs/compiler/compiler.js +13 -2
  3. package/build/cjs/errors/errors.js +7 -0
  4. package/build/cjs/index.d.ts +1 -2
  5. package/build/cjs/index.js +1 -2
  6. package/build/cjs/syntax/parse.d.ts +14 -15
  7. package/build/cjs/syntax/parse.js +6 -5
  8. package/build/cjs/syntax/runtime.d.ts +17 -4
  9. package/build/cjs/syntax/runtime.js +180 -27
  10. package/build/cjs/syntax/static.d.ts +104 -20
  11. package/build/cjs/type/guard/kind.d.ts +3 -0
  12. package/build/cjs/type/guard/kind.js +5 -0
  13. package/build/cjs/type/guard/type.d.ts +3 -0
  14. package/build/cjs/type/guard/type.js +13 -0
  15. package/build/cjs/type/index.d.ts +1 -2
  16. package/build/cjs/type/index.js +1 -2
  17. package/build/cjs/type/module/index.d.ts +1 -0
  18. package/build/cjs/type/{strict → module}/index.js +1 -1
  19. package/build/cjs/type/module/module.d.ts +71 -0
  20. package/build/cjs/type/module/module.js +34 -0
  21. package/build/cjs/type/ref/ref.d.ts +4 -7
  22. package/build/cjs/type/ref/ref.js +3 -11
  23. package/build/cjs/type/static/static.d.ts +1 -1
  24. package/build/cjs/type/type/json.d.ts +4 -17
  25. package/build/cjs/type/type/json.js +52 -68
  26. package/build/cjs/type/type/type.d.ts +1 -2
  27. package/build/cjs/type/type/type.js +55 -57
  28. package/build/cjs/value/cast/cast.js +8 -1
  29. package/build/cjs/value/check/check.js +8 -1
  30. package/build/cjs/value/clean/clean.js +8 -1
  31. package/build/cjs/value/convert/convert.js +7 -0
  32. package/build/cjs/value/create/create.js +7 -0
  33. package/build/cjs/value/default/default.js +7 -0
  34. package/build/cjs/value/transform/decode.js +11 -0
  35. package/build/cjs/value/transform/encode.js +11 -0
  36. package/build/esm/compiler/compiler.d.mts +2 -2
  37. package/build/esm/compiler/compiler.mjs +13 -2
  38. package/build/esm/errors/errors.mjs +7 -0
  39. package/build/esm/index.d.mts +1 -2
  40. package/build/esm/index.mjs +1 -2
  41. package/build/esm/syntax/parse.d.mts +14 -15
  42. package/build/esm/syntax/parse.mjs +6 -5
  43. package/build/esm/syntax/runtime.d.mts +17 -4
  44. package/build/esm/syntax/runtime.mjs +180 -27
  45. package/build/esm/syntax/static.d.mts +104 -20
  46. package/build/esm/type/guard/kind.d.mts +3 -0
  47. package/build/esm/type/guard/kind.mjs +4 -0
  48. package/build/esm/type/guard/type.d.mts +3 -0
  49. package/build/esm/type/guard/type.mjs +12 -0
  50. package/build/esm/type/index.d.mts +1 -2
  51. package/build/esm/type/index.mjs +1 -2
  52. package/build/esm/type/module/index.d.mts +1 -0
  53. package/build/esm/type/module/index.mjs +1 -0
  54. package/build/esm/type/module/module.d.mts +71 -0
  55. package/build/esm/type/module/module.mjs +28 -0
  56. package/build/esm/type/ref/ref.d.mts +4 -7
  57. package/build/esm/type/ref/ref.mjs +3 -11
  58. package/build/esm/type/static/static.d.mts +1 -1
  59. package/build/esm/type/type/json.d.mts +4 -17
  60. package/build/esm/type/type/json.mjs +7 -23
  61. package/build/esm/type/type/type.d.mts +1 -2
  62. package/build/esm/type/type/type.mjs +1 -2
  63. package/build/esm/value/cast/cast.mjs +9 -2
  64. package/build/esm/value/check/check.mjs +9 -2
  65. package/build/esm/value/clean/clean.mjs +9 -2
  66. package/build/esm/value/convert/convert.mjs +7 -0
  67. package/build/esm/value/create/create.mjs +7 -0
  68. package/build/esm/value/default/default.mjs +7 -0
  69. package/build/esm/value/transform/decode.mjs +11 -0
  70. package/build/esm/value/transform/encode.mjs +11 -0
  71. package/package.json +1 -1
  72. package/readme.md +219 -97
  73. package/build/cjs/type/deref/deref.d.ts +0 -22
  74. package/build/cjs/type/deref/deref.js +0 -106
  75. package/build/cjs/type/deref/index.d.ts +0 -1
  76. package/build/cjs/type/deref/index.js +0 -18
  77. package/build/cjs/type/strict/index.d.ts +0 -1
  78. package/build/cjs/type/strict/strict.d.ts +0 -12
  79. package/build/cjs/type/strict/strict.js +0 -16
  80. package/build/esm/type/deref/deref.d.mts +0 -22
  81. package/build/esm/type/deref/deref.mjs +0 -102
  82. package/build/esm/type/deref/index.d.mts +0 -1
  83. package/build/esm/type/deref/index.mjs +0 -1
  84. package/build/esm/type/strict/index.d.mts +0 -1
  85. package/build/esm/type/strict/index.mjs +0 -1
  86. package/build/esm/type/strict/strict.d.mts +0 -12
  87. 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) ? [...references, schema] : references;
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) ? [...references, schema] : references;
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) ? [...references, schema] : references;
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sinclair/typebox",
3
- "version": "0.33.22",
3
+ "version": "0.34.0",
4
4
  "description": "Json Schema Type Builder with Static Type Resolution for TypeScript",
5
5
  "keywords": [
6
6
  "typescript",
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
- - [References](#types-references)
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-references'></a>
773
+ <a name='types-modules'></a>
768
774
 
769
- ### Reference Types
775
+ ### Module Types
770
776
 
771
- Reference types can be created with Ref. These types infer the same as the target type but only store a named `$ref` to the target type.
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
- const Vector = Type.Object({ // const Vector = {
775
- x: Type.Number(), // type: 'object',
776
- y: Type.Number(), // required: ['x', 'y', 'z'],
777
- }, { $id: 'Vector' }) // properties: {
778
- // x: { type: 'number' },
779
- // y: { type: 'number' }
780
- // },
781
- // $id: 'Vector'
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
- const VectorRef = Type.Ref(Vector) // const VectorRef = {
785
- // $ref: 'Vector'
786
- // }
794
+ // Module types must be imported before use.
787
795
 
788
- type VectorRef = Static<typeof VectorRef> // type VectorRef = {
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
- const VertexDeref = Type.Deref(Vertex, [Vector]) // const VertexDeref = {
805
- // type: 'object',
806
- // required: ['position', 'texcoord'],
807
- // properties: {
808
- // position: {
809
- // type: 'object',
810
- // required: ['x', 'y', 'z'],
811
- // properties: {
812
- // x: { type: 'number' },
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 │ '119.8 kb' │ ' 52.6 kb' │ '2.28 x' │
1764
- │ typebox/errors │ ' 74.4 kb' │ ' 33.1 kb' │ '2.25 x' │
1765
- │ typebox/parse │ '115.3 kb' │ ' 48.3 kb' │ '2.39 x' │
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 │ '157.2 kb' │ ' 66.1 kb' │ '2.38 x' │
1768
- │ typebox │ '127.3 kb' │ ' 53.3 kb' │ '2.39 x' │
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 {};