TypeScript 架构实践:从后端接口到 UI 渲染数据流的完整方案

介绍在 TS 中 DTO 与 VO 的思想碰撞与实践,系统性地梳理从后端接口定义前端业务消费的完整链路。

一、 为什么要分 DTO 和 VO?

在 TypeScript 开发中,直接将后端返回的 JSON 数据透传到 UI 界面是研发初期的"捷径",但往往也是后期维护的"噩梦"。为了解决后端字段多变、命名风格不统一(如蛇形命名 vs 驼峰命名)等问题,引入 DTO(数据传输对象)VO(视图对象) 的概念至关重要。

二、 核心思想:职责分离

我们将后端接口数据在系统中的流转拆分为三个关键环节:

环节 承载载体 核心职责
入口层 DTO (Interface) 契约。严格对齐接口协议,描述后端发来的原始数据。
转换层 Mapper 函数 解耦。负责逻辑清洗、字段重命名、类型转换。
应用层 VO (Interface) 纯净。仅包含 UI 层渲染所需的属性,命名符合前端规范。

三、 实战演练:Axios 与泛型的完美结合

为了实现自动化的类型推导,我们通过泛型封装通用的响应结构。

1. 定义通用响应壳子

TypeScript 复制代码
// 统一后端返回的 JSON 格式
export interface ApiResponse<T = any> {
  code: number;
  message: string;
  data: T; // 这里的 T 将被具体的 DTO 替换
}

2. 定义 DTO 与 VO

利用 TS 工具类型(如 Pick)提高定义效率。

TypeScript 复制代码
// 后端原始 DTO
export interface UserDTO {
  id: number;
  user_name: string;
  avatar_url: string;
  created_at: number; // 秒级时间戳
}

// 前端业务 VO
// 挑出需要的字段,并增加/修改业务字段
export type UserVO = Pick<UserDTO, 'id' | 'avatar_url'> & {
  displayName: string;
  regDate: Date; // 转换为 JS Date 对象
};

3. Axios 请求与 Mapper 转换

将 Axios 的泛型能力与转换函数串联起来:

TypeScript 复制代码
import axios from 'axios';

axios.interceptors.response.use((response) => {
  const res = response.data as ApiResponse;
  if (res.code !== 200) {
    // 统一弹出后端给的错误提示
    showToast(res.message);
    return Promise.reject(new Error(res.message));
  }
  return response;
});

// 1. API 层
const fetchUserApi = (id: string) => {
  // 告知 Axios:返回值的 body 是 ApiResponse 结构,其 data 属性是 UserDTO
  return axios.get<ApiResponse<UserDTO>>(`/api/user/${id}`);
};

// 2. Mapper 层:负责 DTO -> VO 的脏活累活
const toUserVO = (dto: UserDTO): UserVO => ({
  id: dto.id,
  avatar_url: dto.avatar_url,
  displayName: dto.user_name || '未知用户',
  regDate: new Date(dto.created_at * 1000)
});

// 3. Service 层:业务组装
async function getUserDetail(id: string): Promise<UserVO> {
  const { data: res } = await fetchUserApi(id);
  // res.data 此时被自动推导为 UserDTO
  return toUserVO(res.data);
}

// 4. UI 层(Vue/React):直接使用 UserVO
const [user, setUser] = useState<UserVO | null>(null);

useEffect(() => {
  getUserDetail('123').then(setUser);
}, []);

总结

这套架构本质上是在前端构建了一道 "类型防火墙"

  • 防火墙外:是不可控的后端原始数据(DTO)。
  • 防火墙内:是稳定的、符合业务习惯的干净数据(VO)。
  • 防火墙中间:是透明的转换逻辑(Mapper)。

通过这种设计,即便后端接口字段发生变更,你只需修改 DTO 定义和 Mapper 函数,UI 层的代码完全不需要改动。

相关推荐
崔庆才丨静觅16 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606117 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了17 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅17 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅17 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅18 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment18 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅18 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊18 小时前
jwt介绍
前端
爱敲代码的小鱼18 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax