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

如何在Wretch中为Resolver添加TypeScript静态类型?

为Wretch的Resolver添加类型实现API调用类型安全

优化后的类型安全实现方案

针对你遇到的问题,推荐两种更简洁的实现方式,既避免重复调用.json<T>(),又不用手写冗长的类型声明:

方案A:利用TypeScript自动推断的泛型工厂函数

去掉手动声明的返回类型,让TypeScript自动推断插件组合后的类型,代码更简洁且类型安全:

import wretch from "wretch";
import FormDataAddon from "wretch/addons/formData";
import QueryStringAddon from "wretch/addons/queryString";

export function apiTyped<T>() {
  return wretch("api-url")
    .errorType("json")
    .resolve((r) => r.json<T>())
    .addon(FormDataAddon)
    .addon(QueryStringAddon);
}

使用方式和之前一致:

export const getUsers = async (): Promise<User[]> =>
  await apiTyped<User[]>().get("/users");

TypeScript会自动推断出返回的Wretch实例类型,无需手动维护复杂的交叉类型。

方案B:为基础API实例创建泛型resolve方法

如果不想每次都创建新的API实例,可以扩展基础实例,添加一个带泛型的resolve方法:

import wretch from "wretch";
import FormDataAddon from "wretch/addons/formData";
import QueryStringAddon from "wretch/addons/queryString";

const baseApi = wretch("api-url")
  .errorType("json")
  .addon(FormDataAddon)
  .addon(QueryStringAddon);

export const api = {
  get<T>(url: string) {
    return baseApi.get(url).resolve(r => r.json<T>());
  },
  post<T>(url: string, data: unknown) {
    return baseApi.post(data, url).resolve(r => r.json<T>());
    // 同理可以扩展put、delete等方法
  }
};

使用方式更直观:

export const getUsers = async (): Promise<User[]> =>
  await api.get<User[]>("/users");

关于你遇到的两种方法的分析

方法1的优缺点

  • 优点:实现简单,无需额外封装,完全贴合Wretch的原生用法
  • 缺点:每个请求都需要手动调用.json<T>(),重复代码较多

方法2的优缺点

  • 优点:封装后调用更简洁,无需重复写.json<T>()
  • 缺点:手动声明返回类型过于冗长,但去掉显式返回类型是完全可行的,TypeScript的自动推断能力足够覆盖插件组合后的类型,不会影响类型安全

无效实现的原因

你尝试的第三种方法之所以报错,是因为:

  1. 调用.resolve((r) => r.json())后,Wretch的返回类型被固定为Promise<unknown>,所以直接赋值给Promise<User[]>会出现类型不匹配
  2. 一旦调用了.resolve(),Wretch的链式调用就已经结束,后续无法再调用.json<T>(),因为resolve已经处理了响应解析逻辑

关于你的疑问解答

这是Wretch的预期使用方式吗?

是的,Wretch的TypeScript设计就是通过泛型来明确响应类型,和原生fetch的差异在于:

  • 原生fetch返回的是Promise<Response>,你手动将整个函数的返回类型声明为Promise<User[]>,本质是一种类型断言
  • Wretch的链式调用会跟踪每一步的类型,所以需要显式指定解析后的类型,避免隐式的类型断言带来的潜在风险

静态类型安全是否属于过度设计?

不属于过度设计。API调用是前端和后端交互的核心环节,静态类型检查能在开发阶段就发现类型不匹配的问题,避免运行时出现解析错误或数据结构异常。当然,你可以根据项目规模选择合适的实现方式:

  • 小型项目:可以用方法1快速实现,接受少量重复代码
  • 中大型项目:推荐用方案B封装统一的API调用方法,既保证类型安全,又能统一处理请求/响应拦截、错误处理等逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 20:23:12