我写了一些代码:

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

我得到一个错误:

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

这是什么意思?


当前回答

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

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

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

其他回答

如果你使用的是material-ui,转到组件的类型定义,它是由TypeScript下划线。你很可能会看到这样的东西

export { default } from './ComponentName';

你有两个选项来解决这个错误:

1.在JSX中使用组件时添加.default:

import ComponentName from './ComponentName'

const Component = () => <ComponentName.default />

2.在导入时,将组件重命名为“default”:

import { default as ComponentName } from './ComponentName'

const Component = () => <ComponentName />

这样就不需要每次使用组件时都指定.default。

如果你将功能组件作为道具传递给另一个组件,请使用以下命令:

import React from 'react';

type RenderGreetingProps = {
  element: React.FunctionComponent<any>
};

function RenderGreeting(props: RenderGreetingProps) {
  const {element: Element} = props;

  return <span>Hello, <Element />!</span>;
}

我通过在导出组件之前使用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>

当声明React Class组件时,使用React。ComponentClass而不是React。组件,那么它将修复ts错误。

你可以使用

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

但是,下面的方法有用吗?

function renderGreeting(Elem: React.ComponentType) {
    const propsToPass = {one: 1, two: 2};

    return <span>Hello, <Elem {...propsToPass} />!</span>;
}