-
Notifications
You must be signed in to change notification settings - Fork 330
/
Encoder.ts
105 lines (87 loc) · 2.34 KB
/
Encoder.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import { pipe } from 'fp-ts/lib/pipeable'
import * as E from '../src/Encoder'
const NumberToString: E.Encoder<string, number> = {
encode: String
}
const BooleanToNumber: E.Encoder<number, boolean> = {
encode: (b) => (b ? 1 : 0)
}
export const OfTest = E.struct({ a: E.id<string>(), b: E.struct({ c: NumberToString }) })
//
// TypeOf
//
export type OfTest = E.TypeOf<typeof OfTest> // $ExpectType { a: string; b: { c: number; }; }
//
// OutputOf
//
export type OfTestOutput = E.OutputOf<typeof OfTest> // $ExpectType { a: string; b: { c: string; }; }
//
// nullable
//
E.nullable(NumberToString) // $ExpectType Encoder<string | null, number | null>
//
// struct
//
E.struct({ a: E.struct({ b: NumberToString }) }) // $ExpectType Encoder<{ a: { b: string; }; }, { a: { b: number; }; }>
//
// partial
//
E.partial({ a: E.partial({ b: NumberToString }) }) // $ExpectType Encoder<Partial<{ a: Partial<{ b: string; }>; }>, Partial<{ a: Partial<{ b: number; }>; }>>
//
// record
//
E.record(NumberToString) // $ExpectType Encoder<Record<string, string>, Record<string, number>>
//
// array
//
E.array(NumberToString) // $ExpectType Encoder<string[], number[]>
//
// tuple
//
E.tuple() // $ExpectType Encoder<[], []>
E.tuple(NumberToString) // $ExpectType Encoder<[string], [number]>
E.tuple(NumberToString, BooleanToNumber) // $ExpectType Encoder<[string, number], [number, boolean]>
//
// intersection
//
pipe(E.struct({ a: NumberToString }), E.intersect(E.struct({ b: BooleanToNumber }))) // $ExpectType Encoder<{ a: string; } & { b: number; }, { a: number; } & { b: boolean; }>
//
// sum
//
const S1 = E.struct({ _tag: E.id<'A'>(), a: NumberToString })
const S2 = E.struct({ _tag: E.id<'B'>(), b: BooleanToNumber })
const sum = E.sum('_tag')
// $ExpectType Encoder<{ _tag: "A"; a: string; } | { _tag: "B"; b: number; }, { _tag: "A"; a: number; } | { _tag: "B"; b: boolean; }>
sum({ A: S1, B: S2 })
export const S3 = E.struct({ _tag: E.id<'C'>(), c: E.id<string>() })
//
// lazy
//
interface A {
a: number
bs: Array<B>
}
interface AOut {
a: string
bs: Array<BOut>
}
interface B {
b: boolean
as: Array<A>
}
interface BOut {
b: number
as: Array<AOut>
}
const A: E.Encoder<AOut, A> = E.lazy(() =>
E.struct({
a: NumberToString,
bs: E.array(B)
})
)
const B: E.Encoder<BOut, B> = E.lazy(() =>
E.struct({
b: BooleanToNumber,
as: E.array(A)
})
)