Typescript - ... 没有兼容的调用签名 [英] Typescript - ... has no compatible call signatures

查看:34
本文介绍了Typescript - ... 没有兼容的调用签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收到不兼容的调用签名错误,不知道该怎么做才能使其正常工作.

i get the no compatible call signatures error and dont know what to do to make it work.

反应状态

     this.state = {
    categoryState: ...,
    categoryItemId
    }

类别声明

let category: Cat1[] | Cat2[] | Cat3[] = this.getCategory();

getMethod 返回类别

getMethod to return category

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) 这是错误发生的地方:

return-Method (react) this is where the error happens:

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

error message: TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((callbackfn: (value: Cat1, index: number, array: Cat1[]) => U, thisArg?: any) => U[] |...' has no compatible call signatures.

推荐答案

2019-03 更新:随着 TypeScript 3.3 的发布,已经有 调用函数类型联合的进展,但不幸的是这痛点仍然存在泛型Array.prototype.map() 之类的方法:

Update 2019-03: With the release of TypeScript 3.3, there has there has been progress for calling a union of function types, but unfortunately this pain point still exists for generic methods like Array.prototype.map():

这是 TypeScript 中的痛点:无法调用函数类型的联合",除非要么接受完全相同的参数,或者 从 TS3.3 开始,如果函数联合中至多一个元素是通用的或重载的.在您的情况下,由于 categoryCat1[] |Cat2[] |Cat3[],方法category.map()本身就是参数不一样的泛型函数的联合;你不能这样称呼.如果 f 是一个接受 Cat1 | 的函数,调用 category.map(f) 应该是安全的.Cat2 |Cat3(这似乎很明显,但涉及理解方法参数的逆变,这很容易混淆).但是,作为链接问题提到,编译器不允许你这样做:

This is a pain point in TypeScript: there's no way to call a "union of function types" unless either they accept exactly the same arguments, or starting in TS3.3, if at most one element of the union of functions is generic or overloaded. In your case, since category is Cat1[] | Cat2[] | Cat3[], the method category.map() is itself a union of generic functions whose parameters are not the same; and you can't call that. It should be safe to call category.map(f) if f is a function which accepts Cat1 | Cat2 | Cat3 (this may seem obvious, but involves understanding contravariance of method arguments, which is easy to get mixed up). But, as the linked issue mentions, the compiler doesn't let you do that:

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

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[] |Cat2[] |Cat3[],但作为 (Cat1 | Cat2 | Cat3)[].只要你只是从数组中读取而不是写入它,那么这样做应该是安全的:

So you get an error. Luckily there are workarounds. The easiest in your case is to treat category not as Cat1[] | Cat2[] | Cat3[], but as (Cat1 | Cat2 | Cat3)[]. As long as you're just reading from the array and not writing to it, it should be safe to do that:

let category: Cat1[] | Cat2[] | Cat3[] = this.getCategory();
const mappableCategory = category as (Cat1 | Cat2 | Cat3)[];

现在您应该能够映射 mappableCategory 而不是 category:

Now you should be able to map over mappableCategory instead of category:

mappableCategory.map((item: any) => { /* ... */ }); // should work now.

(重申:从 mappableCategory 读取是好的,但写入 mappableCategory 可能是错误的,因为它会很乐意接受 Cat1 的元素code>,即使底层 category 是一个 Cat2 数组.所以除非你确定你在做什么,否则不要写它.)

(Just to reiterate: reading from mappableCategory is fine, but writing to mappableCategory could be a mistake, since it will happily accept elements of Cat1, even if the underlying category was an array of Cat2. So don't write to it unless you're sure what you're doing.)

希望对你有帮助.祝你好运!

Hope that helps you. Good luck!

这篇关于Typescript - ... 没有兼容的调用签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆