File tree Expand file tree Collapse file tree 8 files changed +185
-0
lines changed
projects/type-operations/zod-lite Expand file tree Collapse file tree 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