我收到了无兼容的呼叫签名错误,并且不知道如何使其正常工作。
阵营国家
error =0
类别声明
this.state = {
categoryState: ...,
categoryItemId
}
getMethod返回类别
let category: Cat1[] | Cat2[] | Cat3[] = this.getCategory();
return-Method(react)这是错误发生的地方:
private getCategory() {
switch (this.state.categoryState) {
case "Cat1": {
return this.props.cat1 as Cat1[];
}
case "EVENT": {
return this.props.cat2 as Cat2[];
}
default: {
return this.props.cat3 as Cat3[];
}
}
}
错误讯息: TS2349:无法调用类型缺少调用签名的表达式。输入'((callbackfn :(值:Cat1,索引:数字,数组:Cat1 [])=> U,thisArg?:any)=> U [] | ...'没有兼容的呼叫签名。
答案 0 :(得分:4)
2019-03更新:调用函数类型的并集已经取得了进展,但是不幸的是,still exists的痛苦点是Array.prototype.map()
这样的通用方法:
这是TypeScript中的pain point:除非两者接受完全相同的参数,否则,则无法调用“函数类型的统一”,或者,starting in TS3.3函数联合的最多元素是通用或重载。在您的情况下,由于category
是Cat1[] | Cat2[] | Cat3[]
,所以方法category.map()
本身是通用函数的并集,这些通用函数的参数不同。而且你不能打电话。如果category.map(f)
是接受f
的函数,则应该安全地调用Cat1 | Cat2 | Cat3
(这似乎很明显,但是涉及到对contravariance of method arguments的理解,这很容易混淆) 。但是,作为链接问题mentions,编译器不允许您这样做:
当前这是设计使然,因为在获取联合类型的成员时我们不合成交叉呼叫签名-联合类型上仅显示相同的呼叫签名。
所以您得到一个错误。幸运的是,有解决方法。在您的情况下,最简单的方法是将category
视为Cat1[] | Cat2[] | Cat3[]
,而不是(Cat1 | Cat2 | Cat3)[]
。只要您只是从数组中读取而不是写入数组,这样做就应该是安全的:
let category: Cat1[] | Cat2[] | Cat3[] = this.getCategory();
const mappableCategory = category as (Cat1 | Cat2 | Cat3)[];
现在,您应该可以在mappableCategory
而不是category
上进行映射:
mappableCategory.map((item: any) => { /* ... */ }); // should work now.
(仅重申一下:从mappableCategory
读取是好的,但是写入mappableCategory
可能是一个错误,因为即使基础{{ 1}}是Cat1
的数组。因此,除非您确定自己在做什么,否则不要写它。)
希望对您有帮助。祝你好运!