-
-
Notifications
You must be signed in to change notification settings - Fork 168
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a981101
commit 81836d6
Showing
8 changed files
with
185 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# Zod Lite | ||
|
||
> A [Learning TypeScript > Type Operations](https://learning-typescript.com/type-operations) 🍲 entree project. | ||
Kneel before Zod! | ||
|
||
## Setup | ||
|
||
In one terminal, run the TypeScript compiler via the `tsc` script. | ||
For example, to start the TypeScript compiler in watch mode: | ||
|
||
```shell | ||
npm run tsc -- --watch | ||
``` | ||
|
||
In another terminal, run Jest via the `test` script. | ||
For example, to start tests in watch mode: | ||
|
||
```shell | ||
npm run test -- --watch | ||
``` | ||
|
||
## Specification | ||
|
||
Create and export the following functions from `src/index.ts`: | ||
|
||
- `string()`: creates a schema object representing any primitive string | ||
- `literal<Value>(value)`: creates a schema object of a literal string value | ||
- `union<Values>(values)`: creates a schema object representing multiple allowed type constituents | ||
- `object<Properties>(properties)`: creates a schema object representing an object | ||
|
||
Additionally, export an `type Infer<Schema>` that creates a TypeScript type for a schema. | ||
|
||
## Example | ||
|
||
This code: | ||
|
||
```ts | ||
import * as z from "./index"; | ||
|
||
const spySchema = z.object({ | ||
disguise: z.string(), | ||
moniker: z.literal("007"), | ||
plan: z.union([z.literal("active"), z.literal("improvising")]), | ||
}); | ||
|
||
type Spy = z.Infer<typeof spySchema>; | ||
``` | ||
|
||
...create a `Spy` type equivalent to: | ||
|
||
```ts | ||
type Spy = { | ||
disguise: string; | ||
moniker: "007"; | ||
plan: "active" | "improvising"; | ||
}; | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"label": "🍲 Zod Lite", | ||
"position": 3 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
module.exports = { | ||
transform: { | ||
"^.+\\.(t|j)sx?$": [ | ||
"@swc/jest", | ||
{ | ||
jsc: { | ||
target: "es2021", | ||
}, | ||
}, | ||
], | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"name": "the-narrow-trail", | ||
"scripts": { | ||
"test": "jest", | ||
"test:solutions": "cross-env TEST_SOLUTIONS=1 jest", | ||
"tsc": "tsc" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { describe, jest, test } from "@jest/globals"; | ||
import { expectType } from "tsd"; | ||
|
||
import * as index from "./index"; | ||
import * as solution from "./solution"; | ||
|
||
const z = process.env.TEST_SOLUTIONS ? solution : index; | ||
|
||
const mockRandom = jest.spyOn(Math, "random"); | ||
|
||
describe("zod-lite", () => { | ||
test("Spy", () => { | ||
const spySchema = z.object({ | ||
disguise: z.string(), | ||
moniker: z.literal("007"), | ||
plan: z.union([z.literal("active"), z.literal("improvising")]), | ||
}); | ||
expectType<{ | ||
disguise: string; | ||
moniker: "007"; | ||
plan: "active" | "improvising"; | ||
}>({} as index.Infer<typeof spySchema>); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
// Write your functions and type here! ✨ | ||
// You'll need to export them so the tests can use them. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// Primitives | ||
|
||
export interface SchemaString { | ||
primitive: "string"; | ||
zType: "primitive"; | ||
} | ||
|
||
export const string = (): SchemaString => ({ | ||
primitive: "string", | ||
zType: "primitive", | ||
}); | ||
|
||
// Literals | ||
export interface SchemaLiteral<Value> { | ||
value: Value; | ||
zType: "literal"; | ||
} | ||
|
||
export const literal = <Value extends string>( | ||
value: Value | ||
): SchemaLiteral<Value> => ({ | ||
value, | ||
zType: "literal", | ||
}); | ||
|
||
// Unions | ||
export interface SchemaUnion<Values extends any[]> { | ||
values: Values; | ||
zType: "union"; | ||
} | ||
|
||
export const union = <Values extends any[]>( | ||
values: Values | ||
): SchemaUnion<Values> => ({ | ||
values, | ||
zType: "union", | ||
}); | ||
|
||
export type UnwrapSchemaUnion<Values> = Values extends (infer Value)[] | ||
? Infer<Value> | ||
: never; | ||
|
||
// Objects | ||
export interface SchemaObject<Properties> { | ||
properties: Properties; | ||
zType: "object"; | ||
} | ||
|
||
export const object = <Properties>( | ||
properties: Properties | ||
): SchemaObject<Properties> => ({ | ||
properties, | ||
zType: "object", | ||
}); | ||
|
||
export type UnwrapSchemaObject<Properties> = { | ||
[K in keyof Properties]: Infer<Properties[K]>; | ||
}; | ||
|
||
export type Infer<Schema> = | ||
// Primitives (string) | ||
Schema extends SchemaString | ||
? string | ||
: // Literals | ||
Schema extends SchemaLiteral<infer Value> | ||
? Value | ||
: // Unions | ||
Schema extends SchemaUnion<infer Values> | ||
? UnwrapSchemaUnion<Values> | ||
: // Objects | ||
Schema extends SchemaObject<infer Properties> | ||
? UnwrapSchemaObject<Properties> | ||
: never; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"extends": "../../../tsconfig.json", | ||
"include": ["src"] | ||
} |