我收到“不兼容的调用签名”错误,但不知道该怎么做才能使其正常工作。
react 状态
this.state = {
categoryState: ...,
categoryItemId
}
类别声明
let category: Cat1[] | Cat2[] | Cat3[] = this.getCategory();
返回类别的getMethod
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[];
}
}
}
返回方法( react )这是错误发生的地方:
<select value={this.state.categoryItemID} onChange={this.handleSomething}>
{(category && category.length > 0) &&
category.map((item: any) => {
return (
<option value={item.id}
key={item.id}>{item.localizations[this.props.currentLanguage].title}</option>
);
})
}
</select>
错误信息: TS2349:无法调用类型缺少调用签名的表达式。类型“((callbackfn: (value: Cat1, index: number, array: Cat1[]) => U, thisArg?: any) => U[] |...”没有兼容的调用签名。
最佳答案
2019 年 3 月更新:随着 TypeScript 3.3 的发布,出现了 progress for calling a union of function types ,可惜这个痛点still exists对于像 Array.prototype.map() 这样的通用方法:
<小时/>这是一个pain point在 TypeScript 中:无法调用“函数类型的联合”,除非它们接受完全相同的参数,或者 starting in TS3.3 ,如果函数联合中至多有一个元素是通用的或重载的。就您而言,由于 category
是 Cat1[] |类别2[] | Cat3[]
,方法category.map()
本身就是参数不相同的泛型函数的联合;你不能这样称呼。如果 f
是一个接受 Cat1 | 的函数,那么调用
(这可能看起来很明显,但涉及理解 contravariance of method arguments ,这很容易混淆)。但是,正如链接的问题 mentions ,编译器不允许你这样做:category.map(f)
应该是安全的。类别2 | Cat3
This is currently by design because we don't synthesize an intersectional call signature when getting the members of a union type -- only call signatures which are identical appear on the unioned type.
所以你会得到一个错误。幸运的是,有解决方法。在您的情况下,最简单的是将 category
视为不作为 Cat1[] |类别2[] | 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
可能是一个错误,因为它会很乐意接受 Cat1
的元素code>,即使底层 category
是 Cat2
数组。因此,除非您确定自己在做什么,否则不要写入它。)
希望对您有帮助。祝你好运!
关于reactjs - Typescript - ...没有兼容的调用签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59397471/