【问题标题】:TypeScript: JSX element type does not have any construct or call signaturesTypeScript:JSX 元素类型没有任何构造或调用签名
【发布时间】:2018-08-04 12:25:20
【问题描述】:

我正在使用 React 16.2.0、TypeScript 2.7.1,并且 any 不允许作为类型。

主要成分:

// index.js

import * as React from 'react'
import Page from './page'
import i18n from '../i18n'

import PageContent from '../components/pageContent'
import withMoreInfo from '../hoc/withMoreInfo'

class Home extends React.Component {
  render () {
    return <Page title={ i18n.t('home.title') }>
      <PageContent />
    </Page>
  }
}

export default withMoreInfo(Home)

临时文件:

import * as React from 'react'

export default function withMoreInfo<T> (Wrapped: T) {
  return class WithMoreInfo extends React.Component<{ asPath: string }> {
    static async getInitialProps ({ asPath }: { asPath: string }) {
      return { asPath }
    }

    render () {
      const { asPath } = this.props
      const language = asPath.indexOf('/ro') === 0 ? 'ro' : 'en'
      return <Wrapped language={ language } pathname={ asPath } />
    }
  }
}

我无法解决这个错误:error #TS2604: JSX element type 'Wrapped' does not have any construct or call signatures.

非常感谢任何提示。 谢谢,保罗

【问题讨论】:

    标签: reactjs typescript


    【解决方案1】:

    你需要告诉编译器这个参数是一个构造函数,它返回一个带有languagepathname属性的React组件

    function withMoreInfo<T extends React.Component<{ language: string, pathname: string }, any>>(Wrapped: new (props: { language: string, pathname: string }, context?: any) => T) {
        return class WithMoreInfo extends React.Component<{ asPath: string }> {
            static async getInitialProps({ asPath }: { asPath: string }) {
                return { asPath }
            }
    
            render() {
                const { asPath } = this.props
                const language = asPath.indexOf('/ro') === 0 ? 'ro' : 'en'
                return <Wrapped language={language} pathname={asPath} />
            }
        }
    }
    // The component must have properties language and pathname and only those
    class Home extends React.Component<{ language: string, pathname: string }> {
        render() {
            return <div />
        }
    }
    
    export default withMoreInfo(Home)
    

    在您调用withMoreInfo(Home) 的原始版本中,T 确实是一个反应组件,但是您也可以调用withMoreInfo(1),因为T 不受任何限制。泛型函数对于传递给它的任何类型都必须是正确的,因此编译器认为T 可能是任何东西,因此它可以可靠地对此一无所知。 解决方案是让编译器知道,Wrapped 参数是一个反应组件的构造函数,即任何具有属性{ language: string, pathname: string } 的反应组件T。构造函数具有与常规函数类似的签名声明,只是使用 new 关键字,因此 new (props: { language: string, pathname: string }, context?: any) =&gt; T

    【讨论】:

    • 提香,非常感谢您的回复!我一直在寻找这个答案一段时间,并没有看到任何关于这个设置的文章或一段代码。这是宝贵的。 问题 1:我原以为“T”的类型是 Home(它扩展了 React.Component)。必须重新声明扩展是违反直觉的。你能解释一下为什么或给我一个提示/链接在哪里阅读这个? 问题 2:您使用没有名称的“新”指令。 TS 是否从 > 推断它?这对我来说不是很清楚。再次感谢您的宝贵帮助。保罗
    【解决方案2】:

    在这里给出答案,因为它与一般错误相关。

    我在类型定义中缺少new

    some-js-component.d.ts文件:

    import * as React from "react";
    
    export default class SomeJSXComponent extends React.Component<any, any> {
        new (props: any, context?: any)
    }
    

    在我试图导入无类型组件的tsx 文件中:

    import SomeJSXComponent from 'some-js-component'
    
    ...inside render()
       return (
            <React.Fragment>
                <SomeJSXComponent withProps={asdf} />
            </React.Fragment>
       );
    

    【讨论】:

      猜你喜欢
      • 2020-06-08
      • 2022-11-13
      • 2021-11-30
      • 2016-10-07
      • 2016-03-05
      • 2021-09-21
      • 2021-12-26
      • 2017-12-05
      • 1970-01-01
      相关资源
      最近更新 更多