Created
March 3, 2026 22:11
-
-
Save timjb/0b312111da58b88c617f1af1af132767 to your computer and use it in GitHub Desktop.
Zod with Temporal
This file contains hidden or 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
| import "./temporal-polyfill.js"; | |
| import * as z from "zod"; | |
| import * as zt from "zod-temporal"; | |
| interface TimeSchemas { | |
| Instant: z.Schema; | |
| LocalDateTime: z.Schema; | |
| } | |
| const isoSchemas = { | |
| Instant: z.iso.datetime({ offset: false }), | |
| LocalDateTime: z.iso.datetime({ local: true }), | |
| } satisfies TimeSchemas; | |
| const temporalSchemas = { | |
| Instant: zt.instant(), | |
| LocalDateTime: zt.plainDateTime(), | |
| } satisfies TimeSchemas; | |
| const makeUserSchema = <TimeSchemasT extends TimeSchemas>( | |
| timeSchemas: TimeSchemasT, | |
| ) => | |
| z.object({ | |
| joinedAt: timeSchemas.Instant, | |
| joinedAtLocal: timeSchemas.LocalDateTime, | |
| }); | |
| const SerializableUserSchema = makeUserSchema(isoSchemas); | |
| const UserSchema = makeUserSchema(temporalSchemas); | |
| const user = SerializableUserSchema.parse({ | |
| joinedAt: "2024-06-01T12:00:00Z", | |
| joinedAtLocal: "2024-06-01T14:00", | |
| }); | |
| const temporalUser = UserSchema.decode(user); | |
| console.log("Decoded user2:", temporalUser); |
This file contains hidden or 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
| { | |
| "name": "workspace", | |
| "version": "1.0.0", | |
| "description": "", | |
| "main": "index.js", | |
| "scripts": { | |
| "test": "echo \"Error: no test specified\" && exit 1" | |
| }, | |
| "keywords": [], | |
| "author": "", | |
| "license": "ISC", | |
| "type": "module", | |
| "dependencies": { | |
| "@js-temporal/polyfill": "^0.5.1", | |
| "zod": "^4.3.6", | |
| "zod-temporal": "^2.1.1" | |
| }, | |
| "devDependencies": { | |
| "@types/node": "^25.3.3", | |
| "tsx": "^4.21.0", | |
| "typescript": "^5.9.3" | |
| } | |
| } |
This file contains hidden or 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
| import { Temporal } from "@js-temporal/polyfill"; | |
| (globalThis as any).Temporal = Temporal; | |
| export {}; |
This file contains hidden or 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
Show hidden characters
| { | |
| // Visit https://aka.ms/tsconfig to read more about this file | |
| "compilerOptions": { | |
| // File Layout | |
| // "rootDir": "./src", | |
| // "outDir": "./dist", | |
| // Environment Settings | |
| // See also https://aka.ms/tsconfig/module | |
| "module": "nodenext", | |
| "moduleResolution": "nodenext", | |
| "target": "esnext", | |
| "types": ["node"], | |
| // For nodejs: | |
| // "lib": ["esnext"], | |
| // "types": ["node"], | |
| // and npm install -D @types/node | |
| // Other Outputs | |
| "sourceMap": true, | |
| "declaration": true, | |
| "declarationMap": true, | |
| // Stricter Typechecking Options | |
| "noUncheckedIndexedAccess": true, | |
| "exactOptionalPropertyTypes": true, | |
| // Style Options | |
| // "noImplicitReturns": true, | |
| // "noImplicitOverride": true, | |
| // "noUnusedLocals": true, | |
| // "noUnusedParameters": true, | |
| // "noFallthroughCasesInSwitch": true, | |
| // "noPropertyAccessFromIndexSignature": true, | |
| // Recommended Options | |
| "strict": true, | |
| "jsx": "react-jsx", | |
| "verbatimModuleSyntax": true, | |
| "isolatedModules": true, | |
| "noUncheckedSideEffectImports": true, | |
| "moduleDetection": "force", | |
| "skipLibCheck": true, | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment