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

React中API响应类型多变时,如何反序列化为TypeScript类型?

针对不同用户类型的搜索结果反序列化方案

针对你的React+TypeScript场景,以下是几种实用的类型反序列化方案:

方案1:自定义类型守卫(Type Guards)

这是处理联合类型最直接的前端方案,无需修改API,通过检查响应中独有的字段来判别具体类型。

假设你的接口补充示例字段后为:

export interface AnonymousSearchResults {
  basicResults: string[];
}

export interface MemberSearchResults extends AnonymousSearchResults {
  memberExclusiveContent: string[];
}

export interface AdminSearchResults extends MemberSearchResults {
  adminControls: string[];
}

export type SearchResults = AnonymousSearchResults | MemberSearchResults | AdminSearchResults;

编写自定义类型守卫函数:

// 判断是否为会员搜索结果
function isMemberResults(res: SearchResults): res is MemberSearchResults {
  return 'memberExclusiveContent' in res;
}

// 判断是否为管理员搜索结果
function isAdminResults(res: SearchResults): res is AdminSearchResults {
  return 'adminControls' in res;
}

实际使用时:

async function fetchSearchResults() {
  const response = await fetch('/api/search');
  const rawData = await response.json();
  const results = rawData as SearchResults; // 先做基础类型断言

  if (isAdminResults(results)) {
    // TS自动推断results为AdminSearchResults类型
    console.log(results.adminControls);
  } else if (isMemberResults(results)) {
    // TS自动推断results为MemberSearchResults类型
    console.log(results.memberExclusiveContent);
  } else {
    // TS自动推断results为AnonymousSearchResults类型
    console.log(results.basicResults);
  }
}

方案2:标签联合类型(Tagged Union)

如果能协调后端在响应中添加一个标识用户类型的字段(如userType),可以用标签联合类型让TS自动做类型判别,代码更简洁。

调整接口定义:

export interface AnonymousSearchResults {
  userType: 'anonymous';
  basicResults: string[];
}

export interface MemberSearchResults extends AnonymousSearchResults {
  userType: 'member';
  memberExclusiveContent: string[];
}

export interface AdminSearchResults extends MemberSearchResults {
  userType: 'admin';
  adminControls: string[];
}

export type SearchResults = AnonymousSearchResults | MemberSearchResults | AdminSearchResults;

使用时无需额外守卫函数:

async function fetchSearchResults() {
  const response = await fetch('/api/search');
  const results = await response.json() as SearchResults;

  switch(results.userType) {
    case 'admin':
      console.log(results.adminControls);
      break;
    case 'member':
      console.log(results.memberExclusiveContent);
      break;
    case 'anonymous':
      console.log(results.basicResults);
      break;
  }
}

方案3:运行时类型校验库(如Zod)

如果需要严格校验API返回数据的合法性(避免后端返回非法数据导致前端报错),可以用专门的校验库,同时生成TS类型。

以Zod为例,先安装依赖:

npm install zod

定义Schema并生成TS类型:

import { z } from 'zod';

const AnonymousSearchResultsSchema = z.object({
  basicResults: z.array(z.string()),
});

const MemberSearchResultsSchema = AnonymousSearchResultsSchema.extend({
  memberExclusiveContent: z.array(z.string()),
});

const AdminSearchResultsSchema = MemberSearchResultsSchema.extend({
  adminControls: z.array(z.string()),
});

const SearchResultsSchema = z.union([
  AnonymousSearchResultsSchema,
  MemberSearchResultsSchema,
  AdminSearchResultsSchema,
]);

// 从Zod Schema自动生成TS类型
export type SearchResults = z.infer<typeof SearchResultsSchema>;

使用时做数据校验:

async function fetchSearchResults() {
  const response = await fetch('/api/search');
  const rawData = await response.json();
  
  // 校验数据,不符合Schema会抛出错误
  const results = SearchResultsSchema.parse(rawData);

  // 后续可通过字段判断具体类型
  if ('adminControls' in results) {
    console.log(results.adminControls);
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 03:52:53