「JSX要素タイプ '...'には構成または呼び出しの署名がありません」というエラーはどういう意味ですか?


157

私はいくつかのコードを書きました:

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

エラーが発生します:

JSX要素タイプにElemは構成または呼び出しシグネチャがありません

どういう意味ですか?

回答:


196

これは、コンストラクタインスタンスの混同です。

Reactでコンポーネントを作成するときは、次の点に注意してください。

class Greeter extends React.Component<any, any> {
    render() {
        return <div>Hello, {this.props.whoToGreet}</div>;
    }
}

次のように使用します。

return <Greeter whoToGreet='world' />;

あなたはしていない、このようにそれを使用します。

let Greet = new Greeter();
return <Greet whoToGreet='world' />;

最初の例では、我々は周り渡しているGreeterコンストラクタ関数を、当社のコンポーネントの。それが正しい使い方です。2番目の例では、のインスタンスを渡していますGreeter。これは誤りであり、実行時に「オブジェクトは関数ではありません」などのエラーで失敗します。


このコードの問題

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

インスタンスを期待しているということですReact.Componentコンストラクターを取る関数が必要なものReact.Component

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

または同様に:

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

31
これを書いている時点では、@types/reactそれらを使用するのが最も簡単ですfunction RenderGreeting(Elem: React.ComponentType) { ... }
Jthorpe

function renderGreeting(Elem: typeof React.Component)ES6 でどのように書くのですか?
Bruce Sun

ありがとう。ステートレス機能コンポーネントを渡したい場合はどうなるでしょうか?そうだとしfunction renderGreeting (Elem: new() => React.SFC<any>){...}たら、なぜSFCのタイプを次のように宣言するのでしょうか?const Hello:React.SFC<any> = (props) => <div>Hello World</div>ではなく:const Hello: new() =>React.SFC<any> = (props) => <div>Hello World</div>
Ben Carp

1
@JthorpeあなたのコメントはそのIMOでの回答と承認されたものでなければなりません。
トマーシュHübelbauer

export const BackNavigationTextWrapper = (WrappedComponent: typeof React.Component) => { const BackNavigationTextWrappedComponent = (props, { commonElements = {} }: any) => { return <WrappedComponent {...props} backLabel={commonElements.backLabel || 'Go back to reservation details'} /> }; BackNavigationTextWrappedComponent.type = WrappedComponent.type; return BackNavigationTextWrappedComponent; }; 「プロパティ 'type'はタイプ 'typeof Component'に存在しません」というエラーが発生します。
Prakash P

60

コンポーネントクラスをパラメーターとして(インスタンスに対して)取得する場合は、次を使用しますReact.ComponentClass

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

機能コンポーネントが混在React.ComponentType<any>しているので、それらを含めるには、代わりにタイプを使用する必要があります。
ザック

34

JSXからTSXに変換し、一部のライブラリをjs / jsxとして保持し、他のライブラリをts / tsxに変換するとき、TSX \ TSファイル内のjs / jsxインポートステートメントを

import * as ComponentName from "ComponentName";

import ComponentName from "ComponentName";

TSXから古いJSX(React.createClass)スタイルのコンポーネントを呼び出す場合は、

var ComponentName = require("ComponentName")


4
逆の意味ですか?
apieceofbart 2017

5
TypeScript(つまりでtsconfig.json)をに設定する場合、inportステートメントを変更する必要はありませんallowSyntheticDefaultImports。参照:typescriptlang.org/docs/handbook/compiler-options.html およびここでの議論:blog.jonasbandi.net/2016/10/…– jbandi 18
1

11

プロップを本当に気にしない場合、可能な最も広いタイプはReact.ReactTypeです。

これにより、ネイティブのdom要素を文字列として渡すことができます。React.ReactTypeこれらすべてをカバーします:

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

8

material-uiを使用している場合は、TypeScriptで下線が引かれているコンポーネントのタイプ定義に移動します。おそらくあなたはこのようなものを見るでしょう

export { default } from './ComponentName';

エラーを解決するには2つのオプションがあります。

1. .defaultJSXでコンポーネントを使用するときに追加します。

import ComponentName from './ComponentName'

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

2.インポート時に、「デフォルト」としてエクスポートされているコンポーネントの名前を変更します。

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

const Component = () => <ComponentName />

この方法で.defaultは、コンポーネントを使用するたびに指定する必要はありません。


1
これは私の問題を解決するのに役立ちました。
WhiteWalker


2

私の場合、React.ReactNodeタイプではなく機能コンポーネントのタイプとして使用していましたReact.FC

このコンポーネントで正確に:

export const PropertiesList: React.FC = (props: any) => {
  const list:string[] = [
    ' Consequat Phasellus sollicitudin.',
    ' Consequat Phasellus sollicitudin.',
    '...'
  ]

  return (
    <List
      header={<ListHeader heading="Properties List" />}
      dataSource={list}
        renderItem={(listItem, index) =>
          <List.Item key={index}> {listItem } </List.Item>
      }
    />
  )
}


2

@Jthorpeが示唆したように、ComponentClassいずれか一方のみができますComponentPureComponentではなくFunctionComponent

を渡そうとするとFunctionComponent、typescriptは次のようなエラーをスローします...

Type '(props: myProps) => Element' provides no match for the signature 'new (props: myProps, context?: any): Component<myProps, any, any>'.

ただし、どちらの場合も許可するのでComponentTypeはなく、ComponentClassを使用します。反応宣言ファイルごとに、タイプは次のように定義されています...

type ComponentType<P = {}> = ComponentClass<P, any> | FunctionComponent<P>

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'

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

2

React Classコンポーネントを宣言するときに、React.ComponentClass 代わりにを使用React.Componentすると、tsエラーが修正されます。


1

使用できます

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>;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.