为何调用delete和update方法时typescript-eslint报“Unsafe call of an any typed value”?
你遇到的"Unsafe call of an any typed value"错误主要由以下几个核心原因导致:
1. 保留关键字冲突
delete是JavaScript/TypeScript的保留关键字。虽然语法上允许将其作为对象属性名使用,但TypeScript的类型系统在处理这类命名时容易出现推断异常,无法正确识别delete方法的类型,进而被typescript-eslint判定为any类型的不安全调用。这是最可能的触发原因——保留关键字的特殊语法地位会干扰TypeScript对方法类型的追踪。
2. 联合类型的类型推断局限
尽管你的联合类型TResultCategory<TResultProductQueue> | TResultCategory<TCartProduct>的两个成员都拥有delete方法,但TypeScript在处理泛型联合类型时,偶尔会存在推断盲区。不过由于delete方法的签名不依赖泛型参数T,这个原因的可能性较低。
3. 依赖类型未正确定义
如果Dispatch、TResultProductQueue或TCartProduct这些类型未被正确导入或定义(比如遗漏导入语句,或类型本身被隐式推断为any),会导致TResultCategory中的方法签名混入any类型,最终触发typescript-eslint的不安全调用检测。
针对update方法的额外说明
对于update方法的错误,除上述原因外,还存在类型不匹配问题:你传递的unavailableCategoriesQueue[0]?.items可能是TResultProductQueue[]类型(如果第一个元素是TResultCategory<TResultProductQueue>),但update方法要求的参数是TCartProduct[],这种不兼容会进一步加剧TypeScript的类型推断混乱。
- 重命名
delete方法:将delete改为非保留关键字(比如remove),这是最直接的解决方案:
type TResultCategory<T> = { title: string; items: T[]; description?: string; remove(dispatch: Dispatch<{}>): void; update?(dispatch: Dispatch<{}>, products: TCartProduct[]): void; } // 调用时 unavailableCategoriesQueue[0].remove(dispatch);
- 引用式访问保留关键字属性:如果必须保留
delete命名,在类型定义和调用时使用引号包裹:
type TResultCategory<T> = { // ...其他属性 'delete'(dispatch: Dispatch<{}>): void; // ... } // 调用时 unavailableCategoriesQueue[0]['delete'](dispatch);
确保依赖类型完整定义:检查
Dispatch、TResultProductQueue和TCartProduct的类型定义,避免出现any类型的隐式推断。修复
update方法参数类型:确保传递给update的products参数与TCartProduct[]类型匹配,可通过类型断言或转换逻辑实现。
内容的提问来源于stack exchange,提问作者Overground

