我收到了不兼容的呼叫签名错误,并且不知道该怎么做才能使其正常工作。
反应态
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[]; } } }
return-Method(反应),这是发生错误的地方:
<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:(值:Cat1,索引:数字,数组:Cat1 [])=> U,thisArg ?: any)=> U [] | …’没有兼容的呼叫签名。
更新2019-03:随着TypeScript 3.3的发布,调用函数类型的并集已经取得了进展,但不幸的是,对于通用方法来说,这种痛点仍然存在Array.prototype.map():
Array.prototype.map()
这是一个痛点在打字稿:有没有办法来调用,除非“的功能类型union” 要么 他们接受完全相同的参数,或者在TS3.3开始,如果功能的联盟至多有一个元素是通用或超载。在您的情况下,由于categoryis Cat1[] | Cat2[] | Cat3[],所以方法category.map()本身就是通用函数的并集,这些通用函数的参数不相同;而且你不能打电话。category.map(f)如果f是可以接受的函数,则应该安全地调用Cat1 | Cat2 | Cat3(这似乎很明显,但是涉及到理解方法参数的矛盾,这很容易混淆)。但是,作为链接的问题提到,编译器不会让你这样做:
category
Cat1[] | Cat2[] | Cat3[]
category.map()
category.map(f)
f
Cat1 | Cat2 | Cat3
目前,这是设计使然,因为在获取联合类型的成员时我们不合成交叉调用签名-只有 相同的 调用签名才会出现在联合类型上。
所以你得到一个错误。幸运的是,有解决方法。在您的情况下,最简单的方法category不是将视为Cat1[] | Cat2[] | Cat3[],而是将视为(Cat1 | Cat2 | Cat3)[]。只要您只是从数组中读取而不是写入数组,这样做就应该是安全的:
(Cat1 | Cat2 | Cat3)[]
let category: Cat1[] | Cat2[] | Cat3[] = this.getCategory(); const mappableCategory = category as (Cat1 | Cat2 | Cat3)[];
现在您应该可以映射,mappableCategory而不是category:
mappableCategory
mappableCategory.map((item: any) => { /* ... */ }); // should work now.
(只需重申一下:读mappableCategory是可以的,但是写mappableCategory可能是一个错误,因为Cat1即使基础category是数组,它也会很乐意接受的元素Cat2。因此,除非您确定自己要在做。)
Cat1
Cat2
希望对您有帮助。祝好运!