Typescript - ...没有兼容的呼叫签名

时间:2018-06-19 09:28:55

标签: reactjs typescript

我收到了无兼容的呼叫签名错误,并且不知道如何使其正常工作。

阵营国家

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

1 个答案:

答案 0 :(得分:4)

2019-03更新:调用函数类型的并集已经取得了进展,但是不幸的是,still exists的痛苦点是Array.prototype.map()这样的通用方法:


这是TypeScript中的pain point:除非两者接受完全相同的参数,否则,则无法调用“函数类型的统一”,或者,starting in TS3.3函数联合的最多元素是通用或重载。在您的情况下,由于categoryCat1[] | 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的数组。因此,除非您确定自己在做什么,否则不要写它。)

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