TypeScript中如何为Axios请求Promise添加CANCEL回调供Redux-Saga处理?
我希望为Promise添加CANCEL回调,以便Redux-Saga可以处理它。我的代码如下:
import { CANCEL } from 'redux-saga'; cancellableCall = <T = any, E = ApiError>( options: AxiosRequestConfig, validationTemplate?: TemplateType, ): Promise<APIResponse<T, E>> => { const controller = new AbortController(); const request = this.call<T, E>( { ...options, signal: controller.signal, }, validationTemplate, ) as Promise<APIResponse<T, E>>; request[CANCEL] = () => controller.abort(); return request; };
但在request[CANCEL]这行代码处,我遇到了TypeScript警告:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Promise<APIResponse<T, E>>'.
No index signature with a parameter of type 'string' was found on type 'Promise<APIResponse<T, E>>'.ts(7053)
这个错误的核心原因是:TypeScript默认的Promise类型没有定义CANCEL这个额外属性的索引签名,直接给Promise实例添加自定义属性会触发类型检查报错。
可以通过以下两种方式解决:
方式一:全局扩展Promise类型
在项目的类型定义文件(比如types.d.ts)中扩展Promise接口,让TypeScript全局识别CANCEL属性:
import type { CANCEL } from 'redux-saga'; declare global { interface Promise<T> { [CANCEL]?: () => void; } }
之后给request[CANCEL]赋值就不会再触发类型警告,所有Promise实例都会支持这个可选属性。
方式二:局部类型断言绕过检查
如果不想修改全局Promise类型,可以在赋值时用类型断言,临时将request转为包含CANCEL属性的复合类型:
(request as Promise<APIResponse<T, E>> & { [CANCEL]?: () => void })[CANCEL] = () => controller.abort();
这种方式仅作用于当前代码位置,不会影响全局类型定义。
两种方式都能让TypeScript通过类型检查,同时保留Redux-Saga所需的取消回调功能。
内容的提问来源于stack exchange,提问作者Dmitry

