Tấn Phát Digital

Zod Schema Generator - Tạo Zod Schema Từ JSON

Dán JSON để tạo Zod schema và TypeScript type cho Next.js, React Hook Form hoặc API validation.

Input JSON
Kết quả

Hợp tác ngay với Tấn Phát Digital

Chúng tôi không chỉ thiết kế website, mà còn giúp doanh nghiệp xây dựng thương hiệu số mạnh mẽ. Cung cấp dịch vụ thiết kế website trọn gói từ thiết kế đến tối ưu SEO. Hãy liên hệ ngay với Tấn Phát Digital để cùng tạo nên những giải pháp công nghệ đột phá, hiệu quả và bền vững cho doanh nghiệp của bạn tại Hồ Chí Minh.

Sinh Zod schema từ JSON mẫu: kiểm tra dữ liệu lúc chạy cho TypeScript

Công cụ đọc một khối JSON mẫu, duyệt từng trường của object rồi dựng khối z.object tương ứng kèm dòng import và dòng z.infer để lấy kiểu tĩnh. Kết quả là một schema khởi đầu chạy được ngay: nó kiểm tra dữ liệu lúc chương trình chạy, khác hẳn với kiểu TypeScript vốn bị xóa sạch sau khi biên dịch. Phần rule nghiệp vụ như optional, enum hay giới hạn độ dài vẫn là việc bạn tự thêm.

Tính năng nổi bật

  • Đọc JSON mẫu rồi dựng khối z.object đúng theo danh sách trường có trong object đó
  • Suy kiểu tự động: chuỗi ra z.string, số nguyên ra z.number().int(), số thập phân ra z.number(), true/false ra z.boolean(), null ra z.null()
  • Đi sâu vào object lồng nhau theo đệ quy, mỗi cấp sinh một z.object riêng chứ không gộp thành z.any()
  • Mảng được suy từ phần tử đầu tiên thành z.array(kiểu phần tử), mảng rỗng thì trả về z.array(z.any())
  • Sinh sẵn dòng export type bằng z.infer<typeof Schema> nên bạn có luôn kiểu tĩnh đi kèm schema
  • Kèm dòng import { z } from "zod" ở đầu kết quả để khối mã dán thẳng vào file .ts là dùng được
  • Ô tên schema tự chuẩn hóa về PascalCase và tự gắn hậu tố Schema, tên kiểu lấy phần còn lại sau khi bỏ hậu tố đó
  • Dán vào một mảng thì công cụ lấy object đầu tiên làm mẫu; JSON sai cú pháp thì hiện đúng thông báo lỗi của bộ phân tích

Kiểu trong TypeScript biến mất lúc chạy, còn dữ liệu vào thì không

Khai báo một interface rồi ép kiểu response bằng as User không kiểm tra gì cả. Trình biên dịch tin lời bạn, xóa hết chú thích kiểu khi xuất ra JavaScript, và nếu máy chủ trả về createdAt là chuỗi thay vì số thì chương trình vẫn chạy tiếp cho tới khi vỡ ở một chỗ cách đó vài lớp hàm, thường là một lỗi undefined khó lần ngược về nguồn. Đó là lý do người ta cần một lớp kiểm tra thật sự tồn tại lúc chạy, đặt đúng tại ranh giới nhận dữ liệu: response từ API bên thứ ba, body của request, giá trị đọc từ localStorage, biến môi trường, dữ liệu form người dùng gõ vào. Zod làm việc đó, và điểm hay là schema Zod vừa kiểm tra lúc chạy vừa suy ra được kiểu tĩnh, nên bạn không phải duy trì hai bản mô tả cùng một cấu trúc. Việc gõ tay khối z.object cho một object hai ba chục trường thì lại chán và dễ sót trường, nhất là khi có object lồng nhau. Công cụ này lo phần gõ lặp đó để bạn tập trung vào phần thật sự cần suy nghĩ là các rule nghiệp vụ.

Lợi ích khi sử dụng

  • Có ngay khối z.object đủ trường thay vì gõ tay và sót mất vài trường ở cuối object dài
  • Object lồng nhau được dựng theo đúng cấu trúc, đỡ phải đếm ngoặc khi viết bằng tay
  • Dòng z.infer đi kèm giúp kiểu tĩnh và kiểm tra lúc chạy luôn khớp nhau vì cùng sinh từ một nguồn
  • Nhìn thấy toàn bộ trường của một response lạ trong vài giây, hữu ích khi đọc API chưa có tài liệu
  • Chạy hoàn toàn trong trình duyệt nên dán được cả JSON dài mà không phải chờ tải lên
  • Kết quả là mã Zod chuẩn, không phải định dạng riêng, nên chỉnh tiếp bằng tay rất tự nhiên

Năm bước từ JSON mẫu tới schema dùng được

  1. 1Dán một JSON mẫu càng đầy đủ trường càng tốt vào ô bên trái, tốt nhất là một bản ghi thật có đủ mọi trường thay vì bản ghi đang thiếu vài giá trị.
  2. 2Gõ tên schema vào ô phía trên, ví dụ User hoặc Product; công cụ tự chuyển về PascalCase và tự thêm hậu tố Schema nên bạn không cần gõ phần đuôi.
  3. 3Đọc kết quả bên phải, đối chiếu từng dòng với ý định thật: trường nào có thể vắng mặt, trường nào có thể là null, trường nào chỉ nhận một tập giá trị cố định.
  4. 4Bấm nút sao chép rồi dán vào một file .ts trong dự án, đặt cạnh nơi bạn gọi API hoặc khai báo form chứ đừng gom hết vào một file types dùng chung.
  5. 5Bổ sung rule nghiệp vụ: thêm .optional() và .nullable() cho đúng trường, đổi z.string() thành z.enum([...]) khi giá trị có tập hữu hạn, thêm ràng buộc độ dài và định dạng, rồi mới dùng schema để parse dữ liệu thật.

Bảng suy kiểu công cụ đang dùng và những chỗ nó buộc phải đoán

Quy tắc suy kiểu ở đây rất thẳng và bạn nên nắm để biết chỗ nào cần sửa lại. Chuỗi cho ra z.string(). Số được xét thêm một bước: số nguyên cho ra z.number().int(), số có phần thập phân cho ra z.number(). Giá trị true hoặc false cho ra z.boolean(). Mảng lấy phần tử đầu tiên làm đại diện rồi bọc trong z.array, mảng rỗng không có gì để suy nên thành z.array(z.any()). Object được duyệt tiếp theo đệ quy, mỗi cấp là một z.object mới. Riêng null là chỗ đáng lưu ý nhất: công cụ trả về z.null(), tức là một schema chỉ chấp nhận đúng giá trị null và bác bỏ mọi giá trị khác. Gần như chắc chắn đó không phải ý bạn muốn, vì trong bản ghi mẫu trường đó tình cờ đang rỗng chứ bản chất nó là chuỗi hoặc số có thể vắng. Cách sửa là đổi thành dạng kiểu thật rồi thêm .nullable(), ví dụ z.string().nullable(). Điểm cần nhớ tiếp theo là JSON không có kiểu ngày tháng. Một chuỗi 2026-05-12T10:00:00Z vẫn chỉ là chuỗi nên kết quả là z.string(); nếu muốn nhận về đối tượng Date, bạn tự thêm bước chuyển đổi. Và vì công cụ chỉ nhìn đúng một bản ghi, nó không thể biết một trường vắng mặt trong mẫu là do không bắt buộc hay do bạn dán thiếu.

Bốn thứ phải tự thêm sau khi dán: bắt buộc, rỗng, tập giá trị và định dạng

Schema sinh ra coi mọi trường là bắt buộc và chỉ ràng buộc đúng kiểu nguyên thủy, nên có bốn nhóm rule bạn gần như luôn phải bổ sung. Thứ nhất là tính bắt buộc: trường nào có thể vắng khỏi object thì thêm .optional(), khác hẳn với .nullable() vốn dành cho trường có mặt nhưng mang giá trị null; hai khái niệm này hay bị nhầm và Zod phân biệt rõ, muốn cả hai thì dùng .nullish(). Thứ hai là tập giá trị hữu hạn: những trường như status, role, type thường chỉ nhận vài chuỗi cố định, để nguyên z.string() nghĩa là bạn chấp nhận mọi chuỗi rác lọt qua, thay bằng z.enum(["active", "banned"]) thì lỗi chính tả bị chặn ngay tại ranh giới. Thứ ba là định dạng chuỗi: email, URL, UUID đều có kiểm tra sẵn, ở Zod 3 viết là z.string().email() còn bản 4 chuyển sang dạng rút gọn z.email(), nên hãy theo phiên bản đang cài trong dự án. Thứ tư là giới hạn giá trị: .min() và .max() cho độ dài chuỗi và biên số, cộng thêm .refine() cho những rule liên quan nhiều trường như ngày kết thúc phải sau ngày bắt đầu. Bốn nhóm này là phần công cụ không đoán hộ được vì chúng nằm trong nghiệp vụ chứ không nằm trong dữ liệu mẫu.

z.infer và nguyên tắc một nguồn sự thật cho kiểu dữ liệu

Dòng cuối trong kết quả là export type Xxx = z.infer<typeof XxxSchema>, và nó quan trọng hơn vẻ ngoài. Cách làm phổ biến nhưng dở là viết một interface thủ công cho kiểu tĩnh, rồi viết thêm một schema cho việc kiểm tra lúc chạy. Hai bản mô tả đó lệch nhau chỉ sau vài lần sửa: ai đó thêm trường vào interface mà quên thêm vào schema, hoặc ngược lại, và trình biên dịch không hề báo gì vì chúng không liên quan tới nhau. Với z.infer, kiểu được rút ra trực tiếp từ schema nên không thể lệch: sửa schema là kiểu tự đổi theo, và mọi nơi đang dùng kiểu đó sẽ báo lỗi biên dịch nếu không còn hợp. Đây gọi là nguyên tắc một nguồn sự thật, và trong dự án TypeScript nó tiết kiệm rất nhiều lần sửa lặt vặt. Một mẹo đi kèm là phân biệt kiểu đầu vào với kiểu đầu ra khi schema có bước chuyển đổi: z.input lấy hình dạng trước khi chạy transform, z.output tương đương z.infer lấy hình dạng sau khi chạy. Với schema không có transform thì hai kiểu này giống nhau, nhưng khi bạn thêm .transform() để đổi chuỗi thành Date, việc dùng nhầm sẽ khiến kiểu ở lớp gọi bị sai. Nếu cần một bản mô tả cấu trúc độc lập ngôn ngữ để dùng chung cho nhiều nơi thay vì gắn với TypeScript, hãy dựng lược đồ tại /vi/tools/json-schema-generator.

Đặt schema ở đúng ranh giới: route handler, server action và React Hook Form

Schema chỉ có ích khi nằm đúng chỗ dữ liệu bên ngoài đi vào chương trình, và trong một dự án Next.js thường có bốn chỗ như vậy. Chỗ thứ nhất là route handler hoặc API route: đọc body rồi gọi safeParse, nhận về một object có trường success, nhánh thất bại trả mã 400 kèm chi tiết lỗi thay vì để dữ liệu xấu chạy xuống lớp dưới. Nên dùng safeParse thay cho parse ở đây vì parse ném lỗi, còn safeParse trả kết quả để bạn xử lý bằng if, hợp với việc trả về mã trạng thái HTTP. Chỗ thứ hai là server action: tham số vào từ form của trình duyệt nên tuyệt đối không tin, kiểm tra ngay dòng đầu tiên của hàm. Chỗ thứ ba là form phía client: cắm schema vào React Hook Form qua zodResolver trong gói @hookform/resolvers, khi đó thông báo lỗi bạn viết trong schema hiện thẳng dưới ô nhập, và cùng một schema dùng lại được ở phía máy chủ nên rule không bị lệch giữa hai phía. Chỗ thứ tư là biến môi trường: parse process.env ngay khi khởi động để ứng dụng chết sớm với thông báo rõ ràng thay vì chạy nửa chừng rồi lỗi vì thiếu khóa. Một lưu ý thực tế: dữ liệu từ form và từ query string luôn là chuỗi, nên với trường số hãy dùng z.coerce.number() để ép kiểu trước khi kiểm tra thay vì tự parseInt rải rác.

Ba trang sinh schema trên site khác nhau ở chỗ nào

Site có ba công cụ cùng nhận một JSON mẫu nhưng sinh ra ba thứ phục vụ ba tầng khác nhau, chọn nhầm là làm việc thừa. Trang này sinh mã Zod, tức một lớp kiểm tra chạy trong chương trình TypeScript của bạn, sống ở tầng ứng dụng và nói về việc dữ liệu đi vào có hợp lệ hay không. Trang /vi/tools/prisma-schema-generator sinh một khối model cho file schema.prisma, tức mô tả dành cho lớp ORM: nó nói về model, quan hệ giữa các model, migration và cách Prisma ánh xạ kiểu xuống cột thật. Trang /vi/tools/sql-create-table-generator sinh câu lệnh DDL thuần để chạy trực tiếp trong cơ sở dữ liệu, nói về kiểu cột của từng hệ quản trị, khóa chính, khóa ngoại, index và ràng buộc. Dữ liệu vào giống nhau nhưng đầu ra không thay thế được cho nhau: một schema Zod không tạo được bảng, một câu CREATE TABLE không chặn được request xấu. Trong một dự án đầy đủ bạn thường dùng cả hai đầu, Zod ở ranh giới ngoài và Prisma hoặc SQL ở ranh giới trong. Nếu bạn chỉ cần kiểu tĩnh thuần TypeScript không kèm kiểm tra lúc chạy, dùng /vi/tools/json-to-typescript nhẹ hơn. Nếu muốn vẽ toàn bộ mô hình dữ liệu nhiều bảng trước khi viết mã, xem /vi/tools/database-schema-designer.

Câu hỏi thường gặp (FAQ)

Vì sao cần Zod khi TypeScript đã có kiểu rồi?

Kiểu TypeScript chỉ tồn tại lúc biên dịch và bị xóa hoàn toàn khi xuất ra JavaScript, nên nó không kiểm tra được dữ liệu đến từ mạng, từ form hay từ localStorage. Zod là lớp kiểm tra tồn tại lúc chạy, đặt tại ranh giới nhận dữ liệu để chặn giá trị sai ngay chỗ nó đi vào.

Trường null trong JSON mẫu ra z.null(), như vậy có đúng không?

Đúng theo dữ liệu mẫu nhưng thường sai theo ý bạn. z.null() chỉ chấp nhận đúng giá trị null và bác bỏ mọi giá trị khác. Nếu bản chất trường đó là chuỗi có thể rỗng, hãy sửa thành z.string().nullable().

Khác nhau giữa .optional() và .nullable() là gì?

.optional() dành cho trường có thể vắng mặt hoàn toàn khỏi object, tức nhận giá trị undefined. .nullable() dành cho trường luôn có mặt nhưng giá trị là null. Muốn chấp nhận cả hai thì dùng .nullish().

Nên dùng parse hay safeParse?

parse ném lỗi khi dữ liệu không hợp lệ, hợp với chỗ bạn muốn dừng ngay như lúc đọc biến môi trường. safeParse trả về object có trường success để xử lý bằng if, hợp với route handler vì bạn cần trả mã trạng thái thay vì để lỗi văng ra ngoài.

Công cụ có xử lý object lồng nhau không?

Có. Mỗi object con được duyệt tiếp theo đệ quy và sinh một z.object riêng ở đúng cấp của nó, nên cấu trúc nhiều tầng vẫn giữ nguyên hình dạng trong kết quả.

Mảng có nhiều kiểu phần tử khác nhau thì sao?

Công cụ chỉ nhìn phần tử đầu tiên để suy kiểu cho cả mảng. Nếu mảng thật sự trộn nhiều dạng object, bạn cần tự viết z.union hoặc z.discriminatedUnion theo một trường phân biệt.

Vì sao ô tên schema tự đổi chữ và tự thêm đuôi Schema?

Ô nhập chuẩn hóa tên về PascalCase và gắn hậu tố Schema nếu bạn chưa gõ, để tên biến hợp quy ước và để công cụ cắt hậu tố đó ra làm tên kiểu ở dòng z.infer. Gõ user sẽ thành UserSchema và kiểu tương ứng là User.

Dùng schema này với React Hook Form thế nào?

Cài gói @hookform/resolvers rồi truyền zodResolver(YourSchema) vào useForm. Thông báo lỗi khai báo trong schema sẽ hiện ngay dưới ô nhập, và bạn dùng lại đúng schema đó ở phía máy chủ để rule hai phía không lệch nhau.

Trường số trong form luôn bị báo sai kiểu, xử lý ra sao?

Dữ liệu từ form HTML và từ query string luôn là chuỗi. Đổi z.number() thành z.coerce.number() để Zod ép kiểu trước khi kiểm tra, thay vì rải parseInt khắp nơi trong mã xử lý.

Chuỗi ngày ISO có tự thành kiểu ngày không?

Không. JSON không có kiểu ngày tháng nên chuỗi ISO vẫn ra z.string(). Muốn nhận về đối tượng Date, hãy thêm bước chuyển đổi bằng .transform() hoặc dùng schema kiểm tra chuỗi ngày rồi tự khởi tạo Date ở lớp gọi.

Viết thông báo lỗi tiếng Việt cho từng trường được không?

Được. Hầu hết phương thức của Zod nhận tham số thông báo, ví dụ z.string().min(6, "Mật khẩu tối thiểu 6 ký tự"). Với form hướng tới người dùng Việt, nên viết sẵn thông báo tại schema thay vì dịch lại ở tầng giao diện.

Schema sinh ra đã dùng thẳng cho production được chưa?

Chưa nên coi là bản cuối. Nó đúng về danh sách trường và kiểu nguyên thủy, nhưng chưa có tính bắt buộc theo nghiệp vụ, chưa có enum, chưa có ràng buộc độ dài và định dạng. Hãy xem đây là bản nháp đúng cấu trúc rồi bổ sung rule trước khi đưa vào nhánh chính.

Từ khóa liên quan

  • zod schema generator
  • json to zod
  • tạo zod schema từ json
  • zod online
  • zod validation typescript
  • z.infer typescript
  • z.object generator
  • runtime validation typescript
  • kiểm tra dữ liệu lúc chạy
  • validate api response typescript
  • zod nextjs server action
  • zodresolver react hook form
  • zod safeparse
  • zod optional nullable
  • zod enum
  • zod coerce number
  • typescript schema validation
  • sinh schema từ json mẫu

Công cụ Developer Tools liên quan

.env Generator

Tạo file .env và .env.example cho dự án.

.gitignore Generator

Tạo .gitignore cho Node.js, Python, Java.

API Mock Generator

Tạo mock JSON data cho API testing.

API Response Formatter

Format và phân tích API response.

API Tester

Test REST API: GET, POST, PUT, DELETE.

Postman Alternative - API Testing Tool Online với Collections, Environment & File Upload

Postman Alternative miễn phí - Test APIs với Collections, Multiple Environments, Pre-request Scripts, Collection Runner, File Upload (form-data), Tests/Assertions, Code Generation (cURL, JS, Python, Node.js). Browser-based, không cần cài đặt. Save requests, export/import collections, auto-save history. Hỗ trợ Bearer Token, Basic Auth, API Key. Hoàn hảo cho API development và testing.

Swagger API Tester - Test API với OpenAPI/Swagger Spec & Authentication Online

Swagger API Tester miễn phí - Import OpenAPI/Swagger specification và test API endpoints với đầy đủ authentication (Bearer Token/JWT, Basic Auth, API Key). Hỗ trợ OpenAPI 3.0, Swagger 2.0, auto-parse endpoints, parameters, request body. Giao diện như Swagger UI với color-coded methods, grouped endpoints, real-time testing. Hoàn hảo cho API development, testing, debugging secured APIs.

Base Converter

Chuyển đổi Binary, Hex, Base32.

Base64 Encoder

Mã hóa/giải mã Base64.

Binary Converter

Chuyển đổi Decimal, Binary, Hex.

Box Shadow Generator

Tạo CSS box-shadow trực quan.

Chmod Calculator

Tính quyền file Linux.

Dịch vụ của Tấn Phát Digital

Đang xây sản phẩm và cần thêm người làm phần nặng?

Gói giải pháp doanh nghiệp

Nền tảng custom cho ngân hàng, y tế và sàn B2B, chuẩn ISO 27001, GDPR, PCI-DSS, SLA 99.99%.

Từ 50.000.000đXem chi tiết →

Dịch vụ phát triển Blockchain & Web3

Smart contract, dApp và NFT marketplace đa chuỗi, audit bảo mật đầy đủ trước khi lên mainnet.

Từ 50.000.000đXem chi tiết →

Dịch vụ thiết kế website tại Hồ Chí Minh

Website doanh nghiệp, bán hàng và đặt lịch, chuẩn SEO ngay từ cấu trúc, tốc độ tải dưới 3 giây.

Từ 5.000.000đXem chi tiết →

Dịch vụ thiết kế landing page

Trang đích riêng cho từng chiến dịch quảng cáo, tỷ lệ chuyển đổi 3–8%, bàn giao trong 5–21 ngày.

Từ 3.000.000đXem chi tiết →

Tư vấn và báo giá miễn phí trong 24 giờ. Xem toàn bộ dịch vụ

Zalo
Facebook
TAN PHAT DIGITAL
Zalo
Facebook