【问题标题】:Typescript - ... has no compatible call signaturesTypescript - ...没有兼容的调用签名
【发布时间】:2018-11-28 05:07:43
【问题描述】:

我收到不兼容的调用签名错误,不知道该怎么做才能让它工作。

反应状态

     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 (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[] |...' 没有兼容的调用签名。

【问题讨论】:

  • edit 包含您收到的错误消息的确切文本的问题。里面可能有一些细节可以帮助其他人回答你的问题。
  • 是的,并且还指出发生错误的确切行(不仅仅是行号,而是该行的实际内容)
  • 完成:) 你会看一下吗?

标签: reactjs typescript


【解决方案1】:

2019-03 更新:随着 TypeScript 3.3 的发布,已经有了 progress for calling a union of function types,但不幸的是这个痛点 still exists 对于像 Array.prototype.map() 这样的泛型方法:


这是 TypeScript 中的 pain point:没有办法调用“函数类型的联合”,除非或者它们接受完全相同的参数,或者 starting in TS3.3,如果最多一个元素函数的并集是泛型的或重载的。在您的情况下,由于categoryCat1[] | Cat2[] | Cat3[],因此category.map() 方法本身就是参数不相同的泛型函数的联合;你不能这样称呼。如果f 是一个接受Cat1 | Cat2 | Cat3 的函数,那么调用category.map(f) 应该是安全的(这可能看起来很明显,但涉及到理解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 可能是一个错误,因为它会很乐意接受Cat1 的元素,即使底层category 是@ 的数组987654345@。所以除非你确定自己在做什么,否则不要写信给它。)

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

【讨论】:

    猜你喜欢
    • 2019-04-08
    • 2017-12-29
    • 1970-01-01
    • 1970-01-01
    • 2017-03-20
    • 1970-01-01
    • 2019-01-26
    • 1970-01-01
    • 2019-09-23
    相关资源
    最近更新 更多