Skip to content

Commit 28d3352

Browse files
committed
With Options Syntax
1 parent 08600dd commit 28d3352

19 files changed

Lines changed: 1154 additions & 149 deletions

File tree

design/syntax/syntax.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,13 +288,21 @@ const Base = Runtime.Union([
288288
Runtime.Ref('Reference')
289289
])
290290
// ------------------------------------------------------------------
291+
// With
292+
// ------------------------------------------------------------------
293+
const With = Runtime.Union([
294+
Runtime.Tuple([Runtime.Const('with'), Runtime.Ref('JsonObject')]),
295+
Runtime.Tuple([])
296+
])
297+
// ------------------------------------------------------------------
291298
// Factor
292299
// ------------------------------------------------------------------
293300
const Factor = Runtime.Tuple([
294301
Runtime.Ref('KeyOf'),
295302
Runtime.Ref('Base'),
296303
Runtime.Ref('IndexArray'),
297-
Runtime.Ref('Extends')
304+
Runtime.Ref('Extends'),
305+
Runtime.Ref('With')
298306
])
299307
// ------------------------------------------------------------------
300308
// Expr
@@ -649,7 +657,6 @@ const Options = Runtime.Tuple([
649657
// Options generic type, and thus span multiple parsing contexts
650658
//
651659
// ------------------------------------------------------------------
652-
653660
// ------------------------------------------------------------------
654661
// JsonNumber
655662
// ------------------------------------------------------------------
@@ -953,6 +960,7 @@ export const SyntaxModule = new Runtime.Module({
953960
IndexArray,
954961
Extends,
955962
Base,
963+
With,
956964
Factor,
957965
ExprTermTail,
958966
ExprTerm,

design/website/app/frontend/components/home/home.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ export function Home() {
104104
messages={[
105105
H, H,
106106
'High Performance Validation for JSON Schema',
107-
'Runtime TypeScript Emulation using JSON Schema'
107+
'Runtime TypeScript Engine For JSON Schema'
108108
]}
109109
/>
110110
<div className='actions'>

design/website/docs/schema/overview.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Schema
22

3-
High Performance JSON Schema Validator
3+
High Performance Validation for JSON Schema
44

55
## Overview
66

Lines changed: 180 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,190 @@
11
# Script.Syntax
22

3-
The Script function will transform TypeScript types into Json Schema schematics.
3+
The Script function is designed to evaluate most TypeScript type expressions, including raw types, interfaces, type aliases, conditional and mapped expressions, and generics. The Script function returns TypeBox types which are themselves JSON Schema, thus Script can be thought of as a TypeScript-based programmable DSL for the JSON Schema specification.
4+
5+
## Types
6+
7+
Script has support for most TypeScript types and structural constructs. Each type will map into its corresponding TypeBox representation, which can be serialized as JSON Schema or compiled into a validator.
8+
9+
```typescript
10+
// ------------------------------------------------------------------
11+
// Literal
12+
// ------------------------------------------------------------------
13+
const T0 = Type.Script('1') // TLiteral<1>
14+
const T1 = Type.Script('true') // TLiteral<true>
15+
const T2 = Type.Script('"hello"') // TLiteral<"hello">
16+
const T3 = Type.Script('10000n') // TLiteral<10000n>
17+
18+
// ------------------------------------------------------------------
19+
// TemplateLiteral
20+
// ------------------------------------------------------------------
21+
const T4 = Type.Script('`hello${1|2}`') // TTemplateLiteral<'^hello(1|2)$'>
22+
23+
// ------------------------------------------------------------------
24+
// JsonSchema
25+
// ------------------------------------------------------------------
26+
const T5 = Type.Script('any') // TAny
27+
const T6 = Type.Script('unknown') // TUnknown
28+
const T7 = Type.Script('never') // TNever
29+
const T8 = Type.Script('boolean') // TBoolean
30+
const T9 = Type.Script('integer') // TInteger
31+
const T10 = Type.Script('number') // TNumber
32+
const T11 = Type.Script('string') // TString
33+
const T12 = Type.Script('null') // TNull
34+
35+
// ------------------------------------------------------------------
36+
// JavaScript
37+
// ------------------------------------------------------------------
38+
const T13 = Type.Script('bigint') // TBigInt
39+
const T14 = Type.Script('symbol') // TSymbol
40+
const T15 = Type.Script('undefined') // TUndefined
41+
const T16 = Type.Script('void') // TVoid
42+
43+
// ------------------------------------------------------------------
44+
// Structural
45+
// ------------------------------------------------------------------
46+
const T17 = Type.Script('{ x: number }') // TObject<{ x: TNumber }>
47+
const T18 = Type.Script('[1, 2]') // TTuple<[TLiteral<1>, TLiteral<2>]>
48+
const T19 = Type.Script('number[]') // TArray<TNumber>
49+
50+
// ------------------------------------------------------------------
51+
// Intersect
52+
// ------------------------------------------------------------------
53+
const T20 = Type.Script('{ x: 1 } & { y: 2 }') // TIntersect<[
54+
// TObject<{
55+
// x: TLiteral<1>
56+
// }>,
57+
// TObject<{
58+
// y: TLiteral<2>
59+
// }>,
60+
// ]>
61+
62+
// ------------------------------------------------------------------
63+
// Union
64+
// ------------------------------------------------------------------
65+
const T21 = Type.Script('{ x: 1 } | { y: 2 }') // TUnion<[
66+
// TObject<{
67+
// x: TLiteral<1>
68+
// }>,
69+
// TObject<{
70+
// y: TLiteral<2>
71+
// }>,
72+
// ]>
73+
74+
// ------------------------------------------------------------------
75+
// Function
76+
// ------------------------------------------------------------------
77+
const T22 = Type.Script(`(a: number, b: number) => number`)
78+
79+
// TFunction<[TNumber, TNumber], TNumber>
80+
81+
// ------------------------------------------------------------------
82+
// Constructor
83+
// ------------------------------------------------------------------
84+
const T23 = Type.Script(`new (a: number, b: number) => {
85+
foo: (x: string) => void
86+
bar: (x: string) => void
87+
baz: (x: string) => void
88+
}`) // TConstructor<[TNumber, TNumber], TObject<{
89+
// foo: TFunction<[TString], TVoid>
90+
// bar: TFunction<[TString], TVoid>
91+
// baz: TFunction<[TString], TVoid>
92+
// }>>
93+
```
494

595
## Type Expressions
696

7-
The Script function can accept anonymous TypeScript type expressions.
97+
Script provides support for most TypeScript type-level expressions.
898

999
```typescript
10-
const A = Type.Script('"hello"')
100+
// ------------------------------------------------------------------
101+
// Conditional
102+
// ------------------------------------------------------------------
103+
const T0 = Type.Script(`1 extends 2 ? true : false`) // TFalse
104+
const T1 = Type.Script('1 extends infer A ? [A]: never') // TTuple<[TLiteral<1>]>
105+
106+
// ------------------------------------------------------------------
107+
// Mapped
108+
// ------------------------------------------------------------------
109+
const T2 = Type.Script(`{
110+
[K in keyof 'x' | 'y' | 'z']: number
111+
}`) // TObject<{
112+
// x: TNumber,
113+
// y: TNumber,
114+
// z: TNumber
115+
// }>
116+
117+
const T3 = Type.Script(`{
118+
[K in keyof 'x' | 'y' | 'z' as Uppercase<K>]?: number
119+
}`) // TObject<{
120+
// X: TOptional<TNumber>,
121+
// Y: TOptional<TNumber>,
122+
// Z: TOptional<TNumber>
123+
// }>
124+
125+
// ------------------------------------------------------------------
126+
// KeyOf
127+
// ------------------------------------------------------------------
128+
const T4 = Type.Script(`keyof { x: number, y: number }`) // TUnion<[
129+
// TLiteral<'x'>,
130+
// TLiteral<'y'>
131+
// ]>
132+
133+
// ------------------------------------------------------------------
134+
// Indexed
135+
// ------------------------------------------------------------------
136+
const T5 = Type.Script(`[1, 2, 3][2]`) // TLiteral<3>
137+
const T6 = Type.Script(`{ x: number }['x']`) // TNumber
138+
139+
// ------------------------------------------------------------------
140+
// Generic + Invoke
141+
// ------------------------------------------------------------------
142+
const T7 = Type.Script(`<T> = [T, T, T]`) // TGeneric<...>
143+
144+
const T8 = Type.Script({ T7 }, `T7<1>`) // TTuple<[
145+
// TLiteral<1>,
146+
// TLiteral<1>,
147+
// TLiteral<1>,
148+
// ]>
149+
```
11150

12-
const B = Type.Script(`{
13-
x: number
14-
y: number
15-
z: number
16-
}`)
151+
## Type Utilities
17152

18-
const C = Type.Script(`
19-
{ x: number } & (
20-
{ y: number } |
21-
{ z: number }
22-
)`)
153+
Script includes support for most TypeScript utility and intrinsic types.
23154

155+
```typescript
156+
// ------------------------------------------------------------------
157+
// Utility Types
158+
// ------------------------------------------------------------------
159+
const T0 = Type.Script(`Partial<{ x: number }>`)
160+
const T1 = Type.Script(`Required<{ x: number }>`)
161+
const T2 = Type.Script(`Readonly<{ x: number }>`)
162+
const T3 = Type.Script(`Pick<{ x: number, y: number }, 'x'>`)
163+
const T4 = Type.Script(`Omit<{ x: number, y: number }, 'x'>`)
164+
const T5 = Type.Script(`NonNullable<string | null>`)
165+
const T6 = Type.Script('Exclude<1 | 2 | 3, 1 | 2>')
166+
const T7 = Type.Script('Extract<1 | 2 | 3, 1 | 2>')
167+
const T8 = Type.Script('ConstructorParameters<new (x: number) => {}>')
168+
const T9 = Type.Script('Parameters<(x: number) => number>')
169+
const T10 = Type.Script('ReturnType<(x: number) => number>')
170+
const T11 = Type.Script('InstanceType<(x: number) => number>')
171+
172+
// ------------------------------------------------------------------
173+
// Intrinsic String Manipulation
174+
// ------------------------------------------------------------------
175+
const T12 = Type.Script('Uppercase<"hello">')
176+
const T13 = Type.Script('Lowercase<"hello">')
177+
const T14 = Type.Script('Capitalize<"hello">')
178+
const T15 = Type.Script('Uncapitalize<"hello">')
179+
180+
// ------------------------------------------------------------------
181+
// Extension Types
182+
// ------------------------------------------------------------------
183+
const T16 = Type.Script('Evaluate<{ x: number } & { y: number }>')
184+
const T17 = Type.Script('Options<{ x: number }, { additionalProperties: false }>')
24185
```
25186

26-
## Type Alias and Interface
187+
## Type Modules
27188

28189
The Script function also accepts `type` and `interface` declarations. The return value will be an object containing all embedded declarations.
29190

@@ -35,7 +196,7 @@ const { Expression, ConstDeclaration, BinaryExpression, ConstExpression } = Type
35196
| ConstExpression
36197
37198
interface ConstDeclaration {
38-
type: 'ConstDeclaration',
199+
type: 'ConstDeclaration'
39200
name: string
40201
value: Expression
41202
}
@@ -49,21 +210,20 @@ const { Expression, ConstDeclaration, BinaryExpression, ConstExpression } = Type
49210
const: unknown
50211
}
51212
`)
52-
53213
```
54214

55-
# Unsupported
215+
## Unsupported
56216

57217
The following constructs are currently unsupported.
58218

59219
### Template Literal Substring Infer
60220

61-
Script does not support substring inference with TemplateLiteral types.
221+
Script does not support substring inference with `TemplateLiteral` types.
62222

63223
```typescript
64224
type Get<S extends string> = S extends `hello ${infer Name}` ? Name : never
65225
// ^
66-
// Substring Infer Not Supported
226+
// Substring infer not supported
67227
```
68228
69229
### Embedded Function with Generic Type Parameter
@@ -73,5 +233,5 @@ Script does not support embedded function types with generic type parameters.
73233
```typescript
74234
type Foo = { x: <T>(value: T) => string }
75235
// ^
76-
// Embedded Generic Function Not Supported
236+
// Embedded generic function not supported
77237
```

0 commit comments

Comments
 (0)