You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Supabase自动生成的TS类型与Zod同步以验证API数据?

解决方案:从Supabase自动生成的TypeScript类型生成Zod Schema

针对你的需求,以下是两种实用方案,既可以自动同步Supabase数据库结构,又支持添加自定义验证规则:


方案一:使用专用工具自动生成(推荐)

这类工具专门适配Supabase生成的Database类型结构,能一键生成基础Zod Schema,同时允许你通过配置注入自定义验证逻辑。

1. 使用supabase-zod

  • 安装依赖:
    npm install supabase-zod --save-dev
    
  • 创建配置文件(项目根目录下supabase-zod.config.ts):
    import { defineConfig } from "supabase-zod";
    
    export default defineConfig({
      supabaseTypesPath: "./types/supabase.ts", // 你的Supabase类型文件路径
      outputPath: "./src/zod/schemas.ts", // 生成的Zod Schema输出路径
      // 自定义验证规则配置
      customValidations: {
        public: {
          ingredients: {
            Insert: {
              name: (z) => z.string().min(1, "Ingredient name is required"),
              calories: (z) => z.number().nullable().optional().refine(val => val === null || val >= 0, "Calories must be non-negative")
            }
          }
        }
      }
    });
    
  • 添加执行脚本到package.json:
    {
      "scripts": {
        "generate-zod": "supabase-zod generate",
        "update-supabase": "supabase gen types typescript --linked > types/supabase.ts && npm run generate-zod"
      }
    }
    
  • 使用方式:每次更新Supabase数据库结构后,执行npm run update-supabase,即可自动同步生成带自定义规则的Zod Schema。

2. 使用zod-db

这是一款通用型数据库类型转Zod工具,同样支持Supabase类型:

  • 安装依赖:
    npm install zod-db --save-dev
    
  • 编写生成脚本(比如scripts/generate-zod.ts):
    import { generateZodSchemas } from "zod-db";
    import fs from "fs";
    import type { Database } from "../types/supabase";
    
    const schemas = generateZodSchemas<Database>({
      tables: {
        "public.ingredients": {
          insert: {
            name: (schema) => schema.min(1, "Ingredient name is required")
          }
        }
      }
    });
    
    // 将生成的Schema写入文件
    const output = `import { z } from "zod";\n\nexport const ingredientSchema = ${schemas.public.ingredients.Insert.toString()};`;
    fs.writeFileSync("./src/zod/ingredient.ts", output);
    
  • 添加执行脚本到package.json,方便一键更新。

方案二:手动实现类型推导(适合完全自定义场景)

如果不想依赖第三方工具,可以手动基于TypeScript类型映射生成基础Schema,再叠加自定义规则:

步骤1:编写基础Schema生成函数

import { z } from "zod";
import type { Database } from "./types/supabase";

// 定义数据库类型到Zod类型的映射逻辑
type ZodFromDbType<T> =
  T extends string ? z.ZodString :
  T extends number ? z.ZodNumber :
  T extends boolean ? z.ZodBoolean :
  T extends null ? z.ZodNullable<ZodFromDbType<Exclude<T, null>>> :
  z.ZodUnknown;

// 生成指定表的基础Insert Schema
function generateBaseInsertSchema<T extends Record<string, any>>(table: { Insert: T }) {
  const schemaEntries: [string, z.ZodTypeAny][] = [];

  for (const key in table.Insert) {
    type FieldType = T[typeof key];
    let zodType: ZodFromDbType<FieldType>;

    // 匹配基础类型
    if (typeof (table.Insert as any)[key] === "string") {
      zodType = z.string() as ZodFromDbType<FieldType>;
    } else if (typeof (table.Insert as any)[key] === "number") {
      zodType = z.number() as ZodFromDbType<FieldType>;
    } else {
      zodType = z.unknown() as ZodFromDbType<FieldType>;
    }

    // 处理可选字段
    if (key in table.Insert && (table.Insert as any)[key] === undefined) {
      zodType = zodType.optional() as ZodFromDbType<FieldType>;
    }
    // 处理可空字段
    if (null extends FieldType) {
      zodType = zodType.nullable() as ZodFromDbType<FieldType>;
    }

    schemaEntries.push([key, zodType]);
  }

  return z.object(Object.fromEntries(schemaEntries));
}

步骤2:生成Schema并添加自定义规则

// 生成ingredients表的基础Insert Schema
const baseIngredientSchema = generateBaseInsertSchema(Database.public.Tables.ingredients);

// 叠加自定义验证规则
export const ingredientSchema = baseIngredientSchema.extend({
  name: (schema) => schema.min(1, "Ingredient name is required"),
  calories: (schema) => schema.refine(val => val === null || val >= 0, "Calories cannot be negative")
});

保持同步的最佳实践

  • 将Supabase类型更新和Zod Schema生成绑定为一个脚本(如方案一中的update-supabase),避免手动操作遗漏。
  • 使用Git钩子(如pre-commit),在提交代码前自动检查并更新Zod Schema,确保代码库中类型和Schema始终同步。

内容的提问来源于stack exchange,提问作者user12291772

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 04:47:18