小编典典

打字稿-…没有兼容的呼叫签名

reactjs

我收到了不兼容的呼叫签名错误,并且不知道该怎么做才能使其正常工作。

反应态

     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 [] | …’没有兼容的呼叫签名。


阅读 245

收藏
2020-07-22

共1个答案

小编典典

更新2019-03:随着TypeScript
3.3的发布,调用函数类型的并集已经取得了进展,但不幸的是,对于通用方法来说,这种痛点仍然存在Array.prototype.map()


这是一个痛点在打字稿:有没有办法来调用,除非“的功能类型union”
要么
他们接受完全相同的参数,或者在TS3.3开始,如果功能的联盟至多有一个元素是通用或超载。在您的情况下,由于categoryis Cat1[] | Cat2[] | Cat3[],所以方法category.map()本身就是通用函数的并集,这些通用函数的参数不相同;而且你不能打电话。category.map(f)如果f是可以接受的函数,则应该安全地调用Cat1 | Cat2 | Cat3(这似乎很明显,但是涉及到理解方法参数的矛盾,这很容易混淆)。但是,作为链接的问题提到,编译器不会让你这样做:

目前,这是设计使然,因为在获取联合类型的成员时我们不合成交叉调用签名-只有 相同的 调用签名才会出现在联合类型上。

所以你得到一个错误。幸运的是,有解决方法。在您的情况下,最简单的方法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可能是一个错误,因为Cat1即使基础category是数组,它也会很乐意接受的元素Cat2。因此,除非您确定自己要在做。)

希望对您有帮助。祝好运!

2020-07-22