【问题标题】:JSX element type does not have any construct or call signatures. TypescriptJSX 元素类型没有任何构造或调用签名。打字稿
【发布时间】:2018-07-19 22:42:05
【问题描述】:

如果使用compose,则会出现错误JSX element type ‘Option’ does not have any construct or call signatures. 'redux' 版本 - 3.7.2

import * as React from 'react';
import { compose } from 'redux';
import { connect } from 'react-redux';
const { connect: fela, withTheme } = require('react-fela');

const Option = compose(
    ...[
        connect(null,
            dispatch => ({
                onClick: (name) => dispatch(setActive(name)),
            })),
        fela({
            option: ({ theme }) => ({
                ...getControlOptionColors(theme),
            }),
        }),
    ],
)(withTheme(({ label, name, onClick, styles }) => (
    <div className={styles.option} onClick={onClick.bind(this, name)}>{label}</div>
)));

export class Test extends React.PureComponent<any, any> {

    private renderOptions(options) {
        return (
            <div className={this.props.styles.options}>
                {options.map(option => (
                    <div key={option.value}>
                        <Option
                            label={option.label}
                            name={option.value}
                        />
                    </div>
                ))}
            </div>
        );
    }


    public render() {
        const { options } = this.props;
        return (
            <div className={this.props.styles.container}>
                {this.renderOptions(options)}
            </div>
        );
    }
}

export default Controls;

没有撰写,一切正常。

const Element = withTheme(({ label, name, onClick, styles }) => (
        <div className={styles.option} onClick={onClick.bind(this, name)}>{label}</div>
    ))

const conponentWithConnect = connect(null,
    dispatch => ({
        onClick: (name) => dispatch(setActive(name)),
    }))(Element);

const Option = fela({
        option: ({ theme }) => ({
                    ...getControlOptionColors(theme),
        }),
    })(withConnect)

【问题讨论】:

  • 看来 redux 类型有问题

标签: typescript


【解决方案1】:

您需要将 compose 返回的组件类型转换为 React.ComponentType 并且它可以正常工作。所以:

compose(...)(SomeComponent) as React.ComponentType

【讨论】:

  • 这可能确实解决了问题,但使用强制转换 (as) 应该被视为最后的手段,因为它会覆盖类型检查器。如果可能,最好收紧导致类型检查失败的值的类型,和/或插入适当的类型保护,以便 TypeScript 可以正确推断类型。
【解决方案2】:

问题可能是您将 compose 的参数包装在一个数组中,然后使用扩展运算符 (...) 解构该数组。

没有理由这样做,因为它在语义上等同于直接传递参数。这种构造也可能会阻止 TypeScript 正确推断 compose 的类型参数。

您可以将 compose 调用重写为

const Option = compose(
    connect(null,
        dispatch => ({
            onClick: (name) => dispatch(setActive(name)),
        })),
    fela({
        option: ({ theme }) => ({
            ...getControlOptionColors(theme),
        }),
    }),
)(withTheme(({ label, name, onClick, styles }) => (
    <div className={styles.option} onClick={onClick.bind(this, name)}>{label}</div>
)));

这可能会解决问题,但我不能确定,因为您提供的代码 sn-p 不够完整,我无法对其进行测试。

【讨论】:

    【解决方案3】:

    更新的答案;使用compose 的泛型:

    import React, { ComponentType, FC } from 'react';
    
    export default compose<ComponentType>(
      withWidth,
      connect(
        mapStateToProps,
        mapDispatchToProps
      )
    )(Search)
    

    【讨论】:

    • 谢谢!
    猜你喜欢
    • 2020-07-18
    • 2019-04-26
    • 2021-11-30
    • 2016-10-07
    • 2016-03-05
    • 2021-09-21
    • 2021-12-26
    • 2017-12-05
    • 1970-01-01
    相关资源
    最近更新 更多