-
Notifications
You must be signed in to change notification settings - Fork 0
/
mod.ts
56 lines (47 loc) · 1.25 KB
/
mod.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
export declare const N_: unique symbol;
export type N_ = typeof N_;
export type AnyShape =
| Bool
| Num
| Str
| Vec<AnyShape>
| Struct<AnyShape[] | Record<string, AnyShape>>
| Option<AnyShape>
| Enum<([string] | [string, AnyShape])[]>;
export abstract class Shape<N> {
declare [N_]: N;
}
export class Bool extends Shape<boolean> {}
export const bool = new Bool();
export class Num extends Shape<number> {}
export const num = new Num();
export class Str extends Shape<string> {}
export const str = new Str();
export class Vec<T> extends Shape<T[]> {
constructor(readonly element: Shape<T>) {
super();
}
}
export class Struct<Fields extends AnyShape[] | Record<string, AnyShape>>
extends Shape<{ [Key in keyof Fields]: Fields[Key] extends Shape<infer N> ? N : never }>
{
constructor(readonly fields: Fields) {
super();
}
}
export class Option<N> extends Shape<N | undefined> {
constructor(readonly some: Shape<N>) {
super();
}
}
export class Enum<Members extends ([string] | [string, AnyShape])[]> extends Shape<
{
[I in keyof Members]:
& { type: Members[I][0] }
& (Members[I] extends [string, Shape<infer N>] ? { value: N } : {});
}[keyof Members]
> {
constructor(readonly members: Members) {
super();
}
}