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

使用Generator函数中的yield时TypeScript无法推导Promise类型的问题排查

TypeScript Generator中yield Axios请求时类型推导为any的问题

我之前也碰到过一模一样的情况,这其实不是你tsconfig配置遗漏了什么,而是TypeScript对Generator函数里yield的返回值类型推导本身就存在局限。

问题根源

当你在Generator里yield一个Promise(比如axios.get<T>(url)返回的Promise<AxiosResponse<T>>)时,TypeScript默认不知道这个Promise会被外部的迭代器(比如co或者自定义的异步runner)解析成什么值。Generator的类型系统需要明确知道yield出去的值被处理后,回传给Generator内部的具体类型,如果没有显式注解,它就只能默认推导为any。

解决方案

这里有几种方式可以让TypeScript自动推导正确的类型,不用每次手动写AxiosResponse<T>:

1. 显式指定Generator的类型签名

给Generator函数定义完整的类型参数,明确yield出去的类型、Generator最终返回的类型,以及从外部传入Generator的类型(也就是Promise resolve后的值):

import axios, { AxiosResponse } from 'axios';

// 类型签名格式:Generator<YieldType, ReturnType, NextType>
function* foo<T>(): Generator<Promise<AxiosResponse<T>>, void, AxiosResponse<T>> {
  const { data } = yield axios.get<T>(url);
  // 现在 data 会被正确推导为 T 类型
}

这里的NextType就是Promise被resolve后,yield表达式会接收到的类型,TypeScript就能据此自动推导出data的类型。

2. 使用Awaited工具类型简化注解

如果你不想写完整的Generator类型签名,可以用Awaited来提取Promise解析后的类型,代码会更简洁:

import axios from 'axios';

function* foo<T>() {
  const { data }: Awaited<ReturnType<typeof axios.get<T>>> = yield axios.get<T>(url);
  // data 同样会被正确推导为 T 类型
}

ReturnType<typeof axios.get<T>>会获取axios.get<T>的返回类型(也就是Promise<AxiosResponse<T>>),再通过Awaited提取出Promise resolve后的AxiosResponse<T>类型。

3. 结合Generator runner的类型定义

如果你使用像co这样的成熟Generator runner,它的类型定义已经处理了Promise的解析逻辑。只要安装了@types/co,就能借助它的类型自动推导:

import co from 'co';
import axios from 'axios';

function* foo<T>() {
  const { data } = yield axios.get<T>(url);
  // data 会被正确推导为 T 类型
}

// co会自动处理Promise,并让TypeScript识别到yield的返回类型
co(foo<T>());

关于tsconfig的补充说明

你的tsconfig里noImplicitAny: false只是允许隐式any类型存在,但并不会让TypeScript自动推导Generator中yield的异步值类型。哪怕开启strict: true,这个问题依然存在——因为这是Generator类型系统的设计特性,不是配置能解决的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 07:57:46