Skip to content

Commit 2690916

Browse files
committed
Dependent If Type
1 parent 1d1006e commit 2690916

8 files changed

Lines changed: 130 additions & 60 deletions

File tree

design/syntax/syntax.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ const Base = Runtime.Union([
283283
Runtime.Ref('Constructor'),
284284
Runtime.Ref('_Function_'),
285285
Runtime.Ref('Mapped'),
286+
Runtime.Ref('_If_'),
286287
Runtime.Ref('Options'),
287288
Runtime.Ref('GenericCall'),
288289
Runtime.Ref('Reference')
@@ -638,6 +639,14 @@ const Mapped = Runtime.Tuple([
638639
Runtime.Const(RBrace),
639640
])
640641
// ------------------------------------------------------------------
642+
// If
643+
// ------------------------------------------------------------------
644+
const _If_ = Runtime.Union([
645+
Runtime.Tuple([Runtime.Const('if'), Runtime.Ref('Type'), Runtime.Const('then'), Runtime.Ref('Type'), Runtime.Const('else'), Runtime.Ref('Type')]),
646+
Runtime.Tuple([Runtime.Const('if'), Runtime.Ref('Type'), Runtime.Const('then'), Runtime.Ref('Type')]),
647+
Runtime.Tuple([Runtime.Const('if'), Runtime.Ref('Type'), Runtime.Const('else'), Runtime.Ref('Type')])
648+
])
649+
// ------------------------------------------------------------------
641650
// Options
642651
// ------------------------------------------------------------------
643652
const Options = Runtime.Tuple([
@@ -1008,6 +1017,9 @@ export const SyntaxModule = new Runtime.Module({
10081017
MappedOptional,
10091018
MappedAs,
10101019
Mapped,
1020+
1021+
_If_,
1022+
10111023
Reference,
10121024
Options,
10131025

example/index.ts

Lines changed: 15 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,27 @@
1-
import Compile from 'typebox/compile'
2-
import System from 'typebox/system'
3-
import Guard from 'typebox/guard'
4-
import Format from 'typebox/format'
5-
import Schema from 'typebox/schema'
6-
import Value from 'typebox/value'
71
import Type from 'typebox'
82

9-
// ------------------------------------------------------------------
10-
// Settings
11-
// ------------------------------------------------------------------
3+
const { A } = Type.Script(`
4+
type A = {
5+
x: number
6+
y: number
7+
} & if { x: 1 } then { y: 2 } else
8+
if { x: 2 } then { y: 3 } else
9+
never
10+
`)
1211

13-
System.Settings.Set({ enumerableKind: false })
1412

15-
// ------------------------------------------------------------------
16-
// Guard
17-
// ------------------------------------------------------------------
13+
type A = Type.Static<typeof A>
1814

19-
const A = Guard.GraphemeCount('type-📦') // 6
20-
const B = Guard.HasPropertyKey({ x: 1 }, 'x') // true
15+
function test(value: Type.Static<typeof A>) {}
2116

22-
// ------------------------------------------------------------------
23-
// Type
24-
// ------------------------------------------------------------------
17+
test({ x: 1, y: 2 }) // ok
18+
test({ x: 2, y: 3 }) // ok
2519

26-
const T = Type.Object({
27-
x: Type.Number(),
28-
y: Type.Number(),
29-
z: Type.Number()
30-
})
20+
test({ x: 1, y: -1 }) // error: Type '-1' is not assignable to type '2 | 3'
21+
test({ x: 2, y: -1 }) // error: Type '-1' is not assignable to type '2 | 3'
3122

32-
// ------------------------------------------------------------------
33-
// Script
34-
// ------------------------------------------------------------------
3523

36-
const S = Type.Script({ T }, `{
37-
[K in keyof T]: T[K] | null
38-
}`)
3924

40-
// ------------------------------------------------------------------
41-
// Infer
42-
// ------------------------------------------------------------------
25+
console.dir(A)
4326

44-
type T = Type.Static<typeof T>
45-
type S = Type.Static<typeof S>
4627

47-
// ------------------------------------------------------------------
48-
// Parse
49-
// ------------------------------------------------------------------
50-
51-
const R = Value.Parse(T, { x: 1, y: 2, z: 3 })
52-
53-
// ------------------------------------------------------------------
54-
// Compile
55-
// ------------------------------------------------------------------
56-
const C = Compile(S)
57-
58-
const X = C.Parse({ x: 1, y: 2, z: 3 })
59-
60-
// ------------------------------------------------------------------
61-
// Format
62-
// ------------------------------------------------------------------
63-
64-
const E = Format.IsEmail('user@domain.com')
65-
66-
// ------------------------------------------------------------------
67-
// Schema
68-
// ------------------------------------------------------------------
69-
70-
const D = Schema.Parse({ const: 'hello' }, 'hello')

src/type/script/mapping.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,6 +1208,25 @@ export function MappedMapping(input: [unknown, unknown, unknown, unknown, unknow
12081208
)
12091209
}
12101210
// -------------------------------------------------------------------
1211+
// _If_: ['if', Type, 'then', Type, 'else', Type] | ['if', Type, 'then', Type] | ['if', Type, 'else', Type]
1212+
// -------------------------------------------------------------------
1213+
export type T_If_Mapping<Input extends [unknown, unknown, unknown, unknown, unknown, unknown] | [unknown, unknown, unknown, unknown]> = (
1214+
Input extends ['if', infer If extends T.TSchema, 'then', infer Then extends T.TSchema, 'else', infer Else extends T.TSchema]
1215+
? T.TIf<If, Then, Else> :
1216+
Input extends ['if', infer If extends T.TSchema, 'then', infer Then extends T.TSchema]
1217+
? T.TIf<If, Then, T.TNever> :
1218+
Input extends ['if', infer If extends T.TSchema, 'else', infer Else extends T.TSchema]
1219+
? T.TIf<If, T.TNever, Else> :
1220+
never
1221+
)
1222+
export function _If_Mapping(input: [unknown, unknown, unknown, unknown, unknown, unknown] | [unknown, unknown, unknown, unknown]): unknown {
1223+
return (
1224+
Guard.IsEqual(input.length, 6) ? T.If(input[1] as T.TSchema, input[3] as T.TSchema, input[5] as T.TSchema) :
1225+
Guard.IsEqual(input[2], 'then') ? T.If(input[1] as T.TSchema, input[3] as T.TSchema, T.Never()) :
1226+
T.If(input[1] as T.TSchema, T.Never(), input[3] as T.TSchema)
1227+
)
1228+
}
1229+
// -------------------------------------------------------------------
12111230
// Reference: <Ident>
12121231
// -------------------------------------------------------------------
12131232
export type TReferenceMapping<Input extends string,

0 commit comments

Comments
 (0)