File tree 8 files changed +185
-0
lines changed
projects/type-operations/zod-lite
8 files changed +185
-0
lines changed Original file line number Diff line number Diff line change
1
+ # Zod Lite
2
+
3
+ > A [ Learning TypeScript > Type Operations] ( https://learning-typescript.com/type-operations ) 🍲 entree project.
4
+
5
+ Kneel before Zod!
6
+
7
+ ## Setup
8
+
9
+ In one terminal, run the TypeScript compiler via the ` tsc ` script.
10
+ For example, to start the TypeScript compiler in watch mode:
11
+
12
+ ``` shell
13
+ npm run tsc -- --watch
14
+ ```
15
+
16
+ In another terminal, run Jest via the ` test ` script.
17
+ For example, to start tests in watch mode:
18
+
19
+ ``` shell
20
+ npm run test -- --watch
21
+ ```
22
+
23
+ ## Specification
24
+
25
+ Create and export the following functions from ` src/index.ts ` :
26
+
27
+ - ` string() ` : creates a schema object representing any primitive string
28
+ - ` literal<Value>(value) ` : creates a schema object of a literal string value
29
+ - ` union<Values>(values) ` : creates a schema object representing multiple allowed type constituents
30
+ - ` object<Properties>(properties) ` : creates a schema object representing an object
31
+
32
+ Additionally, export an ` type Infer<Schema> ` that creates a TypeScript type for a schema.
33
+
34
+ ## Example
35
+
36
+ This code:
37
+
38
+ ``` ts
39
+ import * as z from " ./index" ;
40
+
41
+ const spySchema = z .object ({
42
+ disguise: z .string (),
43
+ moniker: z .literal (" 007" ),
44
+ plan: z .union ([z .literal (" active" ), z .literal (" improvising" )]),
45
+ });
46
+
47
+ type Spy = z .Infer <typeof spySchema >;
48
+ ```
49
+
50
+ ...create a ` Spy ` type equivalent to:
51
+
52
+ ``` ts
53
+ type Spy = {
54
+ disguise: string ;
55
+ moniker: " 007" ;
56
+ plan: " active" | " improvising" ;
57
+ };
58
+ ```
Original file line number Diff line number Diff line change
1
+ {
2
+ "label" : " 🍲 Zod Lite" ,
3
+ "position" : 3
4
+ }
Original file line number Diff line number Diff line change
1
+ module . exports = {
2
+ transform : {
3
+ "^.+\\.(t|j)sx?$" : [
4
+ "@swc/jest" ,
5
+ {
6
+ jsc : {
7
+ target : "es2021" ,
8
+ } ,
9
+ } ,
10
+ ] ,
11
+ } ,
12
+ } ;
Original file line number Diff line number Diff line change
1
+ {
2
+ "name" : " the-narrow-trail" ,
3
+ "scripts" : {
4
+ "test" : " jest" ,
5
+ "test:solutions" : " cross-env TEST_SOLUTIONS=1 jest" ,
6
+ "tsc" : " tsc"
7
+ }
8
+ }
Original file line number Diff line number Diff line change
1
+ import { describe , jest , test } from "@jest/globals" ;
2
+ import { expectType } from "tsd" ;
3
+
4
+ import * as index from "./index" ;
5
+ import * as solution from "./solution" ;
6
+
7
+ const z = process . env . TEST_SOLUTIONS ? solution : index ;
8
+
9
+ const mockRandom = jest . spyOn ( Math , "random" ) ;
10
+
11
+ describe ( "zod-lite" , ( ) => {
12
+ test ( "Spy" , ( ) => {
13
+ const spySchema = z . object ( {
14
+ disguise : z . string ( ) ,
15
+ moniker : z . literal ( "007" ) ,
16
+ plan : z . union ( [ z . literal ( "active" ) , z . literal ( "improvising" ) ] ) ,
17
+ } ) ;
18
+ expectType < {
19
+ disguise : string ;
20
+ moniker : "007" ;
21
+ plan : "active" | "improvising" ;
22
+ } > ( { } as index . Infer < typeof spySchema > ) ;
23
+ } ) ;
24
+ } ) ;
Original file line number Diff line number Diff line change
1
+ // Write your functions and type here! ✨
2
+ // You'll need to export them so the tests can use them.
Original file line number Diff line number Diff line change
1
+ // Primitives
2
+
3
+ export interface SchemaString {
4
+ primitive : "string" ;
5
+ zType : "primitive" ;
6
+ }
7
+
8
+ export const string = ( ) : SchemaString => ( {
9
+ primitive : "string" ,
10
+ zType : "primitive" ,
11
+ } ) ;
12
+
13
+ // Literals
14
+ export interface SchemaLiteral < Value > {
15
+ value : Value ;
16
+ zType : "literal" ;
17
+ }
18
+
19
+ export const literal = < Value extends string > (
20
+ value : Value
21
+ ) : SchemaLiteral < Value > => ( {
22
+ value,
23
+ zType : "literal" ,
24
+ } ) ;
25
+
26
+ // Unions
27
+ export interface SchemaUnion < Values extends any [ ] > {
28
+ values : Values ;
29
+ zType : "union" ;
30
+ }
31
+
32
+ export const union = < Values extends any [ ] > (
33
+ values : Values
34
+ ) : SchemaUnion < Values > => ( {
35
+ values,
36
+ zType : "union" ,
37
+ } ) ;
38
+
39
+ export type UnwrapSchemaUnion < Values > = Values extends ( infer Value ) [ ]
40
+ ? Infer < Value >
41
+ : never ;
42
+
43
+ // Objects
44
+ export interface SchemaObject < Properties > {
45
+ properties : Properties ;
46
+ zType : "object" ;
47
+ }
48
+
49
+ export const object = < Properties > (
50
+ properties : Properties
51
+ ) : SchemaObject < Properties > => ( {
52
+ properties,
53
+ zType : "object" ,
54
+ } ) ;
55
+
56
+ export type UnwrapSchemaObject < Properties > = {
57
+ [ K in keyof Properties ] : Infer < Properties [ K ] > ;
58
+ } ;
59
+
60
+ export type Infer < Schema > =
61
+ // Primitives (string)
62
+ Schema extends SchemaString
63
+ ? string
64
+ : // Literals
65
+ Schema extends SchemaLiteral < infer Value >
66
+ ? Value
67
+ : // Unions
68
+ Schema extends SchemaUnion < infer Values >
69
+ ? UnwrapSchemaUnion < Values >
70
+ : // Objects
71
+ Schema extends SchemaObject < infer Properties >
72
+ ? UnwrapSchemaObject < Properties >
73
+ : never ;
Original file line number Diff line number Diff line change
1
+ {
2
+ "extends" : " ../../../tsconfig.json" ,
3
+ "include" : [" src" ]
4
+ }
You can’t perform that action at this time.
0 commit comments