JSON Sang TypeScript

Dán JSON và lấy ngay lập tức các interface TypeScript.

Không có dữ liệu nào rời khỏi thiết bị của bạn

Cách sử dụng

  1. Dán JSON của bạn vào bảng bên trái (đối tượng hoặc mảng).
  2. Nhấp Chuyển đổi · các interface TypeScript xuất hiện bên phải.
  3. Điều chỉnh tên gốc và kích hoạt các tùy chọn nếu cần.
  4. Nhấp Sao chép đầu ra để sao chép mã được tạo.

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

Nó có xử lý các đối tượng được lồng nhau không?

Có. Mỗi đối tượng được lồng nhau nhận interface được đặt tên riêng. Các phần tử của các mảng cũng được phân tích để xác định kiểu phần tử.

Điều gì xảy ra với các mảng có các kiểu hỗn hợp?

Nếu một mảng chứa các phần tử các kiểu khác nhau, bộ chuyển đổi sử dụng một kiểu union (vd: string | number).

Nó có hỗ trợ các mảng JSON ở gốc không?

Có. Nếu giá trị gốc là một mảng, bộ chuyển đổi phân tích các phần tử của nó và tạo ra interface phù hợp cũng như một bí danh kiểu cho mảng.

Converter Thực Sự Làm Gì

Nó phân tích JSON của bạn, duyệt qua mọi giá trị, và tạo ra một tập hợp các khai báo interface TypeScript mô tả cấu trúc. Các đối tượng lồng nhau đều có interface riêng được đặt tên, dẫn xuất từ khóa thuộc tính cha theo PascalCase (trường user trở thành interface User). Khi hai đối tượng lồng nhau trùng tên, cái thứ hai được thêm hậu tố số (User, User2). Ở gốc, một mảng trở thành bí danh type Root = RootItem[]; cộng với interface RootItem; một đối tượng trở thành một interface Root duy nhất (hoặc bất kỳ tên nào bạn đặt trong trường «tên gốc»).

Đầu vào và đầu ra mẫu:

// Input
{
  "id": 42,
  "name": "Ada",
  "active": true,
  "tags": ["admin", "billing"],
  "profile": { "bio": "Programmer", "link": null }
}

// Output
export interface Root {
  id: number;
  name: string;
  active: boolean;
  tags: string[];
  profile: Profile;
}

export interface Profile {
  bio: string;
  link: unknown;
}

Bảng ánh xạ kiểu JSON → TypeScript

Giá trị JSONTS được tạo
"hello"string
42 hoặc 3.14number (TS không có kiểu số nguyên riêng)
true / falseboolean
nullunknown (converter không thể biết liệu trường có nullable hay chỉ vắng mặt trong mẫu này)
[]unknown[]
[1, 2, 3]number[]
[1, "x"](number | string)[]
{ "a": 1 }interface được đặt tên

Đối với các mảng đối tượng ở cấp gốc, converter hợp nhất các khóa từ tất cả phần tử thành một interface đại diện duy nhất. Đây là xấp xỉ hợp lý khi các phần tử có cùng cấu trúc, nhưng mất thông tin khi các cấu trúc thực sự phân kỳ (ví dụ: mảng events không đồng nhất). Trong trường hợp đó, bạn cần viết discriminated union bằng tay sau khi tạo.

Tại sao dùng interface cho đối tượng, type cho mảng gốc

TypeScript Handbook chính thức đưa ra gợi ý heuristic một dòng: «Nếu bạn muốn một gợi ý heuristic, hãy dùng interface cho đến khi bạn cần dùng tính năng từ type.» Cả hai đều được định kiểu theo cấu trúc, cả hai đều có thể mô tả cấu trúc đối tượng, nhưng interface vượt trội cho cấu trúc đối tượng vì nó hỗ trợ declaration merging (mở lại interface để thêm trường), hoạt động gọn gàng với extends, và hiển thị theo tên trong lỗi trình biên dịch. Các bí danh type là bắt buộc khi bạn cần union của các kiểu nguyên thủy, intersection của nhiều kiểu, hoặc đặt tên cho thứ không phải đối tượng, đó là lý do mảng ở cấp gốc nhận bí danh type Root = RootItem[]; thay vì interface.

Ghi chú về đặt tên: converter dùng PascalCase không có tiền tố I cổ điển (dùng User thay vì IUser). Các style guide TS hiện đại (của Google, Microsoft, cộng đồng React) hầu như đều bỏ tiền tố này. Tên thuộc tính khớp chính xác với khóa JSON (camelCase nếu JSON dùng camelCase, snake_case nếu dùng snake_case). Các khóa không phải định danh JS hợp lệ (chứa dấu gạch ngang, dấu cách, hoặc bắt đầu bằng chữ số) được đặt trong dấu ngoặc kép: "foo-bar": string;.

Những Gì Công Cụ Này Không Làm (Trung Thực về Giới Hạn)

Một ví dụ JSON đơn lẻ mang ít thông tin hơn schema thực, vì vậy một số điều muốn phát hiện là không thể chỉ từ đầu vào:

Khi Nào Nên Dùng Công Cụ Này

Code-First vs Schema-First vs Trực tiếp (Công cụ này thuộc nhóm nào)

Ba quy trình phổ biến để lấy kiểu TypeScript từ dữ liệu runtime:

Lựa chọn đúng phụ thuộc vào mối quan tâm của bạn là chủ yếu kiểm tra kiểu tĩnh (công cụ này rất tốt) hay còn cả an toàn runtime (hãy dùng Zod / Effect Schema thay thế).

Những Lỗi Phổ Biến

  1. Coi kiểu được tạo là spec hoàn chỉnh. Chúng là điểm khởi đầu hoàn thành 70%. Thêm ? cho các trường tùy chọn, | null nơi thực sự nullable, string literal union nơi có thể.
  2. Tạo từ ví dụ đơn lẻ khi API có biến thể. Đối tượng user đôi khi có email và đôi khi không sẽ tạo ra «email là bắt buộc». Chạy nhiều ví dụ và union kết quả, hoặc chỉnh sửa bằng tay.
  3. Đánh dấu tất cả readonly tự động. Hữu ích cho các luồng dữ liệu bất biến nhưng sai cho các đối tượng trạng thái bạn thay đổi. Hãy dùng toggle readonly có chủ đích.
  4. Tin tưởng độ chính xác trên ID số nguyên lớn. number của JavaScript tối đa là 253−1. Với ID 64-bit, hãy truyền dưới dạng chuỗi và đặt kiểu là string.
  5. Nhầm lẫn interface với type. Các công cụ khác nhau, sự đánh đổi khác nhau. Gợi ý heuristic của TypeScript Handbook là «hãy dùng interface trừ khi bạn cần tính năng chỉ type mới có,» chính xác là những gì công cụ này làm.
  6. Dán JSON bảo mật vào converter phía máy chủ. Phản hồi API thực thường chứa dữ liệu khách hàng, thông tin xác thực, ID nội bộ. Chuyển đổi chỉ trên trình duyệt (công cụ này) giữ dữ liệu trên máy của bạn.

Câu Hỏi Thường Gặp Thêm

Tại sao tất cả trường của tôi được đánh dấu là bắt buộc?

Vì một ví dụ JSON đơn lẻ không thể cho converter biết trường nào đôi khi vắng mặt trong API thực. Mọi khóa xuất hiện trong ví dụ đều trở thành bắt buộc. Nếu bạn biết một trường là tùy chọn, hãy thêm ? ở cuối bằng tay: email?: string;. Để phát hiện tùy chọn đa mẫu, CLI quicktype phức tạp hơn xử lý điều này một cách tự nhiên.

Tại sao trường null của tôi có kiểu là unknown?

Vì converter không thể biết từ một null đơn lẻ liệu trường có luôn nullable (string | null) hay chỉ tình cờ null trong mẫu này (string). unknown là mặc định an toàn; TypeScript sẽ buộc bạn thu hẹp kiểu trước khi dùng giá trị, an toàn hơn any. Hãy chỉnh sửa thành string | null bằng tay khi bạn biết ý định của API.

Tôi nên dùng interface hay type?

Gợi ý heuristic chính thức của TypeScript Handbook: dùng interface cho đến khi bạn cần tính năng chỉ type mới có, chủ yếu là union type, intersection type, hoặc đặt tên cho một kiểu nguyên thủy. Converter này tuân theo quy tắc đó: interface cho mọi cấu trúc đối tượng, type cho bí danh mảng gốc. Một số style guide khuyến nghị mặc định dùng type thay thế (Matt Pocock đã lập luận điều này công khai) nhưng mặc định thông thường là interface cho đối tượng.

JSON của tôi có được tải lên đâu không?

Không. Quá trình chuyển đổi là một JavaScript IIFE độc lập phân tích JSON của bạn qua JSON.parse, duyệt qua giá trị, và ghi kết quả TypeScript vào textarea. Không có fetch, không có lời gọi analytics mang nội dung JSON, không có máy chủ. Điều này quan trọng vì phản hồi API thực thường chứa dữ liệu khách hàng, ID nội bộ, hoặc thông tin xác thực mà bạn không muốn đi qua bên thứ ba.

JSDoc, Zod hoặc runtime validation thì sao?

Công cụ này chỉ tạo kiểu TypeScript lúc biên dịch: không có runtime validator (không có Zod / Yup / Effect Schema), không có comment JSDoc. Nếu bạn cần runtime validation đồng thời là kiểu tĩnh, hãy viết schema trong Zod và dùng z.infer<typeof Schema> của Zod để suy ra kiểu. Nếu bạn có JSON Schema và muốn cả runtime validation lẫn kiểu TS, json-schema-to-typescript + AJV là sự kết hợp thông thường.

Tại sao tên interface không có tiền tố I?

Vì hầu hết các style guide TypeScript hiện đại đều bỏ nó. TypeScript Style Guide của Google khuyến nghị chống lại nó rõ ràng; cộng đồng React đã thống nhất dùng PascalCase không có tiền tố. Quy ước IUser cổ điển đến từ ảnh hưởng của C# / Java đối với TypeScript ban đầu; thực hành hiện tại là dùng User thuần túy.

Công cụ liên quan

Công cụ Định Dạng & Xác Thực JSON Trực Tuyến Miễn Phí Trình Chuyển Đổi JSON Sang Cấu Trúc Go Trình Tạo JSON Schema