From 4ba88cad04c4de1f1bc389c8532a72c5044b4c61 Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Tue, 7 Oct 2025 16:20:34 -0600 Subject: [PATCH] Add schema validation example to mutations guide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Show how to use schema validation libraries (Zod, Valibot, Yup, etc.) with createOptimisticAction for type-safe, runtime-validated actions. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- docs/guides/mutations.md | 66 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/docs/guides/mutations.md b/docs/guides/mutations.md index c6e3967ef..8bd9ec43d 100644 --- a/docs/guides/mutations.md +++ b/docs/guides/mutations.md @@ -492,6 +492,72 @@ const Todo = () => { } ``` +### Type-Safe Actions with Schema Validation + +For better type safety and runtime validation, you can use schema validation libraries like Zod, Valibot, or others. Here's an example using Zod: + +```tsx +import { createOptimisticAction } from "@tanstack/react-db" +import { z } from "zod" + +// Define a schema for the action parameters +const addTodoSchema = z.object({ + text: z.string().min(1, "Todo text cannot be empty"), + priority: z.enum(["low", "medium", "high"]).optional(), +}) + +// Use the schema's inferred type for the generic +const addTodo = createOptimisticAction>({ + onMutate: (params) => { + // Validate parameters at runtime + const validated = addTodoSchema.parse(params) + + // Apply optimistic state + todoCollection.insert({ + id: crypto.randomUUID(), + text: validated.text, + priority: validated.priority ?? "medium", + completed: false, + }) + }, + mutationFn: async (params) => { + // Parameters are already validated + const validated = addTodoSchema.parse(params) + + const response = await fetch("/api/todos", { + method: "POST", + body: JSON.stringify({ + text: validated.text, + priority: validated.priority ?? "medium", + completed: false, + }), + }) + const result = await response.json() + + await todoCollection.utils.refetch() + return result + }, +}) + +// Use with type-safe parameters +const Todo = () => { + const handleClick = () => { + addTodo({ + text: "🔥 Make app faster", + priority: "high", + }) + } + + return