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

React.js+TypeScript中如何校验fetch API响应的返回类型

Fetch API 运行时响应类型校验实现方案

首先明确核心前提:TypeScript 的类型定义仅在编译阶段生效,运行时会被完全擦除,因此仅给 fetch 响应标注类型属于编译时的类型断言,不会触发任何运行时校验。要实现响应不匹配预设类型就抛出错误的效果,必须额外搭配运行时校验逻辑。

实现思路

  • 编写与TS类型对应的运行时校验规则,通常用类型守卫函数实现
  • 封装通用 fetch 处理方法,拿到原始响应数据后先执行校验逻辑
  • 校验不通过直接抛出错误,校验通过则返回带正确类型标注的数据

代码改造示例

第一步:编写类型守卫校验函数

针对你定义的TodoData类型,编写对应的校验逻辑:

interface TodoData {
  id: number,
  userId: number,
  title: string,
  completed: boolean,
}

// 单个TodoData结构校验
function isTodoData(data: unknown): data is TodoData {
  return (
    typeof data === 'object' &&
    data !== null &&
    'id' in data && typeof (data as TodoData).id === 'number' &&
    'userId' in data && typeof (data as TodoData).userId === 'number' &&
    'title' in data && typeof (data as TodoData).title === 'string' &&
    'completed' in data && typeof (data as TodoData).completed === 'boolean'
  )
}

// TodoData数组结构校验
function isTodoDataArray(data: unknown): data is TodoData[] {
  return Array.isArray(data) && data.every(isTodoData)
}

第二步:封装带校验的通用fetch方法

async function fetchWithValidate<T>(
  url: string,
  validator: (data: unknown) => data is T
): Promise<T> {
  const res = await fetch(url)
  // 先校验请求状态
  if (!res.ok) throw new Error(`请求异常,状态码:${res.status}`)
  const rawResponse = await res.json()
  // 执行类型校验
  if (!validator(rawResponse)) {
    throw new Error('响应数据结构不符合预设类型要求')
  }
  return rawResponse
}

第三步:改造原有业务代码

import React, { useEffect, useState } from 'react';
import './App.css';

type Test = {
  name: string;
  age?: number;
}

const App: React.FC<Test> = ({name, age}) => {
  // 给state标注正确类型
  const [todos, setTodos] = useState<TodoData[] | null>(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const todoData = await fetchWithValidate(
          'https://jsonplaceholder.typicode.com/todos',
          isTodoDataArray
        );
        setTodos(todoData);
      } catch (error) {
        // 可统一处理请求错误或类型校验错误
        console.error(error);
      }
    }
    fetchData();  
  },[])

  return (
    <div className="App">
      <p>Hello {name} your age is {age? age: "not given here."}</p>
    </div>
  );
}

export default App;

优化方案

如果校验的类型结构比较复杂,不想手写大量类型守卫代码,可以使用Schema校验类库自动生成类型定义和校验逻辑,减少重复代码量。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 02:54:07