我写了一些代码:

function renderGreeting(Elem: React.Component<any, any>) {
    return <span>Hello, <Elem />!</span>;
}

我得到一个错误:

JSX元素类型Elem没有任何构造或调用签名

这是什么意思?


当前回答

我通过在导出组件之前使用Type Assertions来解决这个问题。TypeScript在使用redux 'compose'组合后无法识别,因此我将道具类型分为IParentProps和IProps,并在做类型断言时使用IParentProps

import { compose } from 'react-redux'
import HOC1 from 'HOCs/HOC1'
import HOC2 from 'HOCs/HOC2'

type IParentProps = {}
type IProps = {}

const Component: React.FC<IProps & IParentProps> = React.memo((props) => {

      return <SomeComponent {...props}/>

})

return compose(HOC1,HOC2)(Component) as React.FunctionComponent<IParentProps>

其他回答

在我的例子中,我在类型定义中缺少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'

const NewComp = ({ asdf }: NewProps) => <SomeJSXComponent withProps={asdf} />

如果你真的不关心道具,那么最广泛的可能类型是React.ElementType。

这将允许将原生dom元素作为字符串传递。反应。ElementType涵盖了所有这些:

renderGreeting('button');
renderGreeting(() => 'Hello, World!');
renderGreeting(class Foo extends React.Component {
   render() {
      return 'Hello, World!'
   }
});

当我从JSX转换到TSX时,我们保留了一些库作为js/ JSX,并将其他库转换为ts/ TSX,我几乎总是忘记更改TSX\ ts文件中的js/ JSX导入语句

import * as ComponentName(组件名);

to

import ComponentName from "ComponentName"

如果从TSX调用旧的JSX (React.createClass)样式组件,则使用

变量

如果你想把一个组件类作为参数(而不是一个实例),使用React。ComponentClass:

function renderGreeting(Elem: React.ComponentClass<any>) {
    return <span>Hello, <Elem />!</span>;
}

看起来现在有一个特殊的新TypeScript类型来解决这个问题:JSXElementConstructor。如果你让某人将构造函数传递给一个未知的ReactElement,而不是该ReactElement的实例,这是传递的正确类型。

const renderGreeting = (Elem: JSXElementConstructor<any>) => {
    return <span>Hello, <Elem />!</span>;
}

这等价于上面选择的正确答案,因为:在JSX中使用<Elem />(也就是用尖括号将大写变量括起来)等效于使用new关键字调用JSX元素的构造函数。