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

Redux-Saga调用API后响应类型定义及Unknown Error处理

Next.js 13 + TypeScript 中 Redux-Saga 类型优化方案

一、为 Generator 泛型定义 Response 类型

首先明确 API 响应的结构,先声明对应的类型接口,再通过 Redux-Saga 的 Generator 泛型约束 yield 返回值的类型。

步骤1:定义 API 响应类型

根据实际响应结构创建 TypeScript 接口:

// 定义笔记列表的响应结构
interface NoteListResponse {
  status: number;
  data: Array<{
    id: string;
    title: string;
    content: string;
    // 补充其他实际返回的字段
  }>;
  // 响应的其他顶层字段也需在此定义
}

步骤2:修改 Generator 泛型参数

Redux-Saga 的 Generator 泛型包含三个参数:

  1. 第一个参数:Yield 类型,即 yield call(...) 返回值的类型,对应 CallEffect<NoteListResponse>
  2. 第二个参数:函数返回类型,此 worker 无返回值,填 void
  3. 第三个参数:Next 类型,即调用 next() 传入值的类型,无需时填 unknown

修改后的 worker 函数:

import { call, put, CallEffect } from 'redux-saga/effects';

function* getNoteListWorker(): Generator<CallEffect<NoteListResponse>, void, unknown> {
  try {
    // 直接调用 apiService.get,无需额外包裹 async 函数
    const response: NoteListResponse = yield call(apiService.get, "/note/list");
    console.log(response);
    if (response.status === 200) {
      yield put(NoteAction.getNoteListSuccess(response.data));
    }
  } catch (error) {
    // 后续处理 error 的 unknown 类型
  }
}

注意:原代码中把 apiService.get 包裹在 async 函数里是多余的,call 可直接接收返回 Promise 的函数和参数,类型推导会更准确。

二、处理 Catch 中的 Unknown 类型错误

TypeScript 中 catch 块的 error 默认类型是 unknown,需通过类型收窄安全访问其属性,避免直接断言为 any。

方案:类型收窄判断

假设使用 Axios 作为请求库,可直接利用 AxiosError 类型判断;若为自定义错误,可通过属性检查收窄类型:

import { AxiosError } from 'axios';

// ... 前面的代码

function* getNoteListWorker(): Generator<CallEffect<NoteListResponse>, void, unknown> {
  try {
    // ... 请求逻辑
  } catch (error) {
    let errorMessage = '未知错误';
    
    // 1. 判断是否为 Axios 请求错误
    if (error instanceof AxiosError) {
      errorMessage = error.response?.data?.message || '请求失败';
    } 
    // 2. 判断是否为普通 Error 实例
    else if (error instanceof Error) {
      errorMessage = error.message;
    }
    // 3. 其他未知错误场景
    
    yield put(NoteAction.getNoteListFail(errorMessage));
  }
}

如果 API 错误响应有固定结构,也可自定义错误类型并通过类型守卫判断:

// 自定义 API 错误类型
interface ApiError {
  response: {
    data: {
      message: string;
    };
  };
}

// 类型守卫函数
function isApiError(error: unknown): error is ApiError {
  return typeof error === 'object' && error !== null && 'response' in error;
}

// 在 catch 中使用
catch (error) {
  let errorMessage = '未知错误';
  if (isApiError(error)) {
    errorMessage = error.response.data.message;
  } else if (error instanceof Error) {
    errorMessage = error.message;
  }
  yield put(NoteAction.getNoteListFail(errorMessage));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 17:42:44