← 返回博客

JSON 转换为 TypeScript:类型和接口指南

学习将 JSON 转换为 TypeScript 类型和接口。涵盖工具、最佳实践和 Zod 运行时验证。

Big JSON Team11 分钟阅读programming
B

Big JSON Team

Technical Writer

Expert in JSON data manipulation, API development, and web technologies. Passionate about creating tools that make developers' lives easier.

11 分钟阅读

# JSON 转换为 TypeScript:类型和接口指南

将 JSON 数据转换为 TypeScript 类型是现代 Web 开发的关键实践。它提供编译时安全性、自动完成和更好的开发体验。

为什么将 JSON 转换为 TypeScript?

编译时安全

interface User {

id: number;

name: string;

}

const user: User = {

id: 1,

name: "张三"

// age: 30 ❌ 错误:'age' 不存在于类型 'User'

};

更好的自动完成

使用 TypeScript 类型,您的 IDE 可以:

  • ✅ 显示可用字段
  • ✅ 显示字段类型
  • ✅ 检查拼写错误
  • ✅ 提供重构工具

错误检测

const user: User = {

id: "123", // ❌ 类型错误:字符串而不是数字

name: "张三"

};

快速示例

JSON 数据

{

"id": 1,

"name": "张三",

"email": "zhang@example.com",

"active": true,

"roles": ["admin", "user"]

}

手动创建的 TypeScript 接口

interface User {

id: number;

name: string;

email: string;

active: boolean;

roles: string[];

}

// 使用

const user: User = JSON.parse(jsonString);

console.log(user.name); // ✓ 类型安全

JSON 到 TypeScript 类型映射

基本类型

| JSON 类型 | TypeScript 类型 |

|-----------|-----------------|

| 字符串 | string |

| 数字 | number |

| 布尔值 | boolean |

| null | null |

| 数组 | T[]Array |

| 对象 | interfacetype |

示例

// 简单类型

{

"name": "张三" // string

"age": 30, // number

"active": true, // boolean

"deleted": null, // null

}

// 数组

{

"tags": ["json", "typescript"] // string[]

"scores": [95, 87, 92] // number[]

"users": [{ ... }] // User[]

}

// 嵌套对象

{

"user": {

"id": 1,

"profile": {

"bio": "开发者"

}

}

}

处理可选和可空字段

可选字段(可能未定义)

interface User {

id: number;

name: string;

middleName?: string; // 可选:可能未定义

}

// 使用

const user: User = {

id: 1,

name: "张三"

// middleName 是可选的

};

可空字段(可能为 null)

interface User {

id: number;

name: string;

deletedAt: string | null; // 可空:可能为 null

}

// 使用

const user: User = {

id: 1,

name: "张三",

deletedAt: null // 或日期字符串

};

既可选又可空

interface User {

id: number;

name: string;

nickname?: string | null; // 既可选又可空

}

// 所有这些都有效

const user1: User = { id: 1, name: "张三" };

const user2: User = { id: 1, name: "张三", nickname: null };

const user3: User = { id: 1, name: "张三", nickname: "小张" };

数组和嵌套对象

简单数组

interface User {

id: number;

name: string;

tags: string[]; // 字符串数组

scores: number[]; // 数字数组

}

对象数组

interface Post {

id: number;

title: string;

}

interface User {

id: number;

name: string;

posts: Post[]; // Post 对象数组

}

嵌套对象

interface User {

id: number;

name: string;

profile: {

bio: string;

avatar: string;

location: {

city: string;

country: string;

};

};

}

更好的方式:分离接口
interface Location {

city: string;

country: string;

}

interface Profile {

bio: string;

avatar: string;

location: Location;

}

interface User {

id: number;

name: string;

profile: Profile;

}

在线工具:quicktype.io

最简单的转换方法

步骤:
  • 访问 https://quicktype.io
  • 选择"JSON"作为源语言
  • 粘贴您的 JSON
  • 在右侧选择"TypeScript"
  • 复制生成的代码
  • 快速类型的特点

    • ✅ 多种输出格式
    • ✅ 自定义选项
    • ✅ 实时预览
    • ✅ 支持 Schema

    配置选项

    在生成之前自定义:

    • 接口 vs 类型: 选择输出风格
    • 可选属性: 处理缺失字段
    • 运行时验证: 生成验证器

    quicktype CLI

    对于自动化和脚本化转换。

    安装

    npm install -g quicktype

    基本用法

    # 将 JSON 文件转换为 TypeScript
    

    quicktype -o User.ts -l typescript data.json

    # 从 URL 读取 JSON

    quicktype -o User.ts -l typescript https://api.example.com/users

    # 指定类型名

    quicktype --type-name User -o User.ts data.json

    # 生成接口而不是类型

    quicktype --lang typescript --interface-name User data.json

    批量转换

    # 转换多个文件
    

    for file in *.json; do

    quicktype "$file" -o "${file%.json}.ts"

    done

    VS Code 扩展

    Paste JSON as Code(QuickType)

    安装:
  • 打开 VS Code
  • 转到扩展
  • 搜索"Paste JSON as Code"
  • 点击安装
  • 使用:
  • 复制 JSON(到剪贴板)
  • 打开 TypeScript 文件
  • Ctrl+Shift+V 或 Cmd+Shift+V
  • 自动生成类型
  • JSON Schema 与 TypeScript

    从 Schema 生成类型

    # 使用 json-schema-to-typescript
    

    npm install -g json-schema-to-typescript

    # 生成类型

    json2ts schema.json > User.ts

    优点

    • ✅ 单一信息来源
    • ✅ 可重用 Schema
    • ✅ 运行时验证

    处理特殊数据类型

    日期

    // 作为字符串(ISO 8601)
    

    interface Post {

    createdAt: string; // "2026-01-13T10:00:00Z"

    }

    // 更好:使用 Date

    interface Post {

    createdAt: Date;

    }

    // 解析时转换

    const post = JSON.parse(jsonString);

    post.createdAt = new Date(post.createdAt);

    正则表达式

    interface Config {
    

    pattern: string; // 存储为字符串

    }

    // 使用时

    const config: Config = JSON.parse(jsonString);

    const regex = new RegExp(config.pattern);

    区分联合类型

    interface Cat {
    

    type: "cat";

    meow: string;

    }

    interface Dog {

    type: "dog";

    bark: string;

    }

    type Pet = Cat | Dog;

    // 类型守卫

    function describe(pet: Pet): string {

    switch (pet.type) {

    case "cat":

    return pet.meow;

    case "dog":

    return pet.bark;

    }

    }

    运行时验证

    Zod

    Zod 提供运行时验证和类型推断。

    安装:
    npm install zod
    定义 Schema:
    import { z } from 'zod';
    
    

    const UserSchema = z.object({

    id: z.number(),

    name: z.string(),

    email: z.string().email(),

    active: z.boolean(),

    middleName: z.string().optional()

    });

    // 自动生成类型

    type User = z.infer<typeof UserSchema>;

    验证数据:
    const data = JSON.parse(jsonString);
    
    

    try {

    const user: User = UserSchema.parse(data);

    console.log("✓ 有效用户");

    } catch (error) {

    console.log("✗ 无效数据:", error.errors);

    }

    Pydantic(Python)

    from pydantic import BaseModel
    

    from typing import Optional

    class User(BaseModel):

    id: int

    name: str

    email: str

    active: bool

    middle_name: Optional[str] = None

    # 从 JSON 解析

    user = User.parse_raw(json_string)

    # 验证和转换

    print(user.name) # 类型安全

    处理 API 响应

    常见 API 响应结构

    interface ApiResponse<T> {
    

    success: boolean;

    data: T;

    error?: string;

    timestamp: string;

    }

    interface User {

    id: number;

    name: string;

    }

    // 使用泛型

    const response: ApiResponse<User[]> = JSON.parse(apiJson);

    if (response.success) {

    response.data.forEach(user => {

    console.log(user.name);

    });

    }

    分页

    interface PaginatedResponse<T> {
    

    data: T[];

    pagination: {

    page: number;

    limit: number;

    total: number;

    hasMore: boolean;

    };

    }

    const response: PaginatedResponse<User> = JSON.parse(json);

    最佳实践

    1. 从准确开始,然后精化

    // ✗ 太宽泛
    

    interface User {

    [key: string]: any;

    }

    // ✓ 准确

    interface User {

    id: number;

    name: string;

    email: string;

    }

    2. 使用工具生成,然后自定义

    // 使用 quicktype 生成,然后:
    

    // - 添加方法

    // - 改进字段名

    // - 添加注释

    interface User {

    id: number;

    name: string;

    // 自定义方法

    getDisplayName(): string {

    return this.name.toUpperCase();

    }

    }

    3. 组织相关类型

    // user-types.ts
    

    export interface User {

    id: number;

    name: string;

    profile: Profile;

    }

    export interface Profile {

    bio: string;

    avatar: string;

    }

    // 在应用中使用

    import { User, Profile } from './user-types';

    4. 分离业务逻辑

    // types.ts - 从 API 的原始数据
    

    interface ApiUser {

    id: number;

    firstName: string;

    lastName: string;

    }

    // domain.ts - 业务逻辑

    interface User extends ApiUser {

    fullName: string;

    }

    // 转换函数

    function toUser(apiUser: ApiUser): User {

    return {

    ...apiUser,

    fullName: ${apiUser.firstName} ${apiUser.lastName}

    };

    }

    工具比较

    | 工具 | 速度 | 自定义 | 最佳用途 |

    |------|------|--------|---------|

    | quicktype.io | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 快速转换 |

    | VS Code 扩展 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | 集成工作流 |

    | Zod | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 运行时验证 |

    | 手动编写 | ⭐⭐ | ⭐⭐⭐⭐⭐ | 完全控制 |

    常见模式

    可区分联合

    type Result<T> = 
    

    | { status: 'success'; data: T }

    | { status: 'error'; error: string };

    const result: Result<User> = JSON.parse(json);

    if (result.status === 'success') {

    console.log(result.data.name);

    }

    可选属性的缺省值

    interface Config {
    

    port?: number;

    host?: string;

    }

    const config: Config = {

    port: 3000,

    host: 'localhost'

    };

    const port = config.port ?? 8000; // 缺省值

    故障排除

    问题:任何类型太宽泛

    // ✗ 避免
    

    const user: any = JSON.parse(json);

    // ✓ 正确

    const user: User = JSON.parse(json);

    问题:缺少字段类型

    使用 quicktype 或手动指定所有字段。

    问题:API 返回不一致的数据

    使用 Zod 进行运行时验证和转换。

    结论

    将 JSON 转换为 TypeScript 类型是现代 Web 开发的关键:

    • 工具(quicktype): 快速开始
    • 运行时验证(Zod): 确保数据安全
    • 类型精化: 维护代码质量
    • 最佳实践: 组织和可重用

    选择适合您的方法,保持类型安全!

    Share:

    相关文章

    Read in English