reactjs - Typescript - ...没有兼容的调用签名

标签 reactjs typescript

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

react 状态

     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[];
            }
        }
    }

返回方法( 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[] |...”没有兼容的调用签名。

最佳答案

2019 年 3 月更新:随着 TypeScript 3.3 的发布,出现了 progress for calling a union of function types ,可惜这个痛点still exists对于像 Array.prototype.map() 这样的通用方法:

<小时/>

这是一个pain point在 TypeScript 中:无法调用“函数类型的联合”,除非它们接受完全相同的参数,或者 starting in TS3.3 ,如果函数联合中至多有一个元素是通用的或重载的。就您而言,由于 categoryCat1[] |类别2[] | Cat3[],方法category.map()本身就是参数不相同的泛型函数的联合;你不能这样称呼。如果 f 是一个接受 Cat1 | 的函数,那么调用 category.map(f) 应该是安全的。类别2 | Cat3 (这可能看起来很明显,但涉及理解 contravariance of method arguments ,这很容易混淆)。但是,正如链接的问题 mentions ,编译器不允许你这样做:

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[] |类别2[] | 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 的元素code>,即使底层 categoryCat2 数组。因此,除非您确定自己在做什么,否则不要写入它。)

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

关于reactjs - Typescript - ...没有兼容的调用签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59397471/

相关文章:

javascript - React - 尝试验证文本字段输入 - "event.target.setValue is not a function"

json - 什么是 axios.defaults.headers.post 'content-type' = 'application/json'

javascript - 如何在 React 中正确使用 Ajax

javascript - typescript :如何在构造函数之外初始化类属性

javascript - 我的 Provider 组件中的语法错误是什么?

javascript - react img 标签问题与 url 和类

angular - Typescript - 如何在 map 中设置对象键的值

javascript - 如何使用 TypeScript 中的钩子(Hook)在 React PureComponent 中键入 Prop ?

node.js - NPM 如何启动 Angular 和 Typescript 应用程序?

javascript - Nestjs 日志响应数据对象