Typescript: jSX要素タイプにはv3.2.0-rcの構成または呼び出しシグネチャがありません

作成日 2018年11月21日  ·  27コメント  ·  ソース: microsoft/TypeScript

TypeScriptバージョン: 3.2.0-rc、3.2.1

コード

import * as React from "react";
import { Component, ReactType} from "react";
function App(props:{component:ReactType}) {
  const Comp: ReactType = props.component
  return (<Comp />)
}

予想される行動:
TypeScript3.1.6として正常に出力する必要があります

実際の動作:
TS2604: JSX element type 'Comp' does not have any construct or call signatures.

Bug JSTSX Duplicate

最も参考になるコメント

私にとっての解決策は次のとおりです。

export type WrapperProps = {
    mainApp: React.ElementType
}

全てのコメント27件

これには残りのエラーメッセージがありませんが、確かに、最新バージョンの@types/reactを使用していて、node_modulesまたはロックファイルに重複が残っていないことを確認してください。

編集:あなたはおそらくReactTypeではなくComponentTypeを使用することを意味します

@Kovensky

私は必ず、最新の使用して作成してもらってください@types/react 16.7.7と重複なし@types/reactyarn.lock
問題の原因が@types/reactの重複である場合、エラーDuplication of definition ...が返されます。

"typescript": "^3.1.6"に戻すと、正常に動作します。

Typescript 3.2.1

他の例


interface P1 {
  p?: boolean
  c?: string
}

interface P2 {
  p?: boolean
  c?: any // if you replace c with string, error goes away
  d?: any
}

declare var C: React.ComponentType<P1> | React.ComponentType<P2>


const a = <C p={true} /> // element does not have any ...

この問題は、新しい「null許容判別式」の変更に関連しているようです。 tsはこれらのタイプの共通インターフェースを見つけることができないようです。
他の例

interface P1 {
  p?: any
  c?: string // remove this and it's ok
}

interface P2 {
  p?: boolean
}

同様の問題があります。簡単な例です。

import * as React from 'react'

//
// Types
//

interface Config<P> {
  ElementType: React.ReactType<P>
}

interface EmptyProps {
}

interface Props {
  a?: string
}

type HProps = {
  configEmpty: Config<EmptyProps>,
  config: Config<Props>
}

//
// Component
//

const H: React.FC<HProps> = ({ config, configEmpty }) => {
  const A: React.ReactType<EmptyProps> = configEmpty.ElementType // assigned
  const B: React.ReactType<EmptyProps> = 'div' // assigned

  const C: React.ReactType<Props> = config.ElementType // assigned
  const D: React.ReactType<Props> = 'div' // in this case assignment failed

  return (
    <div>
      <A/> {/* TS2604: JSX element type 'A' does not have any construct or call signatures. */}
      <B/>

      <C/>
      <D/>
    </div>
  )
}

export default H

AB同じタイプであるため、この動作は完全に無効であると思いBDは_類似したタイプ_がありますが、 Dは割り当てられません🤔

リポジトリ内のコード: https

constを使用しているため、そうではありません。 Aのタイプはtypeof configEmpty.ElementTypeですが、 Bのタイプは'div'です。 letを使用すると、両方で同じ動作が表示されます。

@Kovensky ACどうですか? なぜ、 C作品ながら、 Aで失敗does not have any constructエラー?

これは、 ReactTypeのタイプを改善して、提供している小道具を受け取ることができないコンポーネントを除外したためです。 どのDOM要素も{ a: string | undefined }受け取ることができないため、それらはすべて除外され、関数/クラスコンポーネントのみを割り当てることができます。

@Kovenskyありがとうございます👍割り当ての問題は私には明らかですが、これはどうですか?

import * as React from 'react'

//
// Types
//

interface Config<P> {
  ElementType: React.ReactType<P>
}

interface Empty {}
interface Props { a?: string }

type HProps = {
  configEmpty: Config<Empty>,
  config: Config<Props>
}

//
// Component
//

const H: React.FC<HProps> = ({ config, configEmpty }) => {
  const A: React.ReactType<Empty> = configEmpty.ElementType // is React.ReactType<Empty>
  const B: React.ReactType<Empty> = 'div' // is string
  const C: React.ReactType<Props> = config.ElementType // is React.ReactType<Props>

  return (
    <div>
      {/* React.ReactType<Empty> */} <A/> {/* <--- TS2604: JSX element type 'A' does not have any construct or call signatures. */}
      {/* React.ReactType<Empty> */} <B/>
      {/* React.ReactType<Props> */} <C/>
    </div>
  )
}

export default H

ABは明らかに定義されたタイプが同じですが、なぜAが失敗するのですか? それは本当に紛らわしいことです。

@rexpan@goloveychukのエラーは、条件付きJSXコンストラクターに基づく#28795と#28768に似ていると思います。

うーん、問題は、 ReactType<any>が_すべての組み込みjsxタグ_の和集合を返すことです(さらにComponentType<any>ですが、その部分は問題ありません)。これらのコンポーネントの署名は簡単には単純化されません(他のすべてを完全に包含する署名ではありません)。 これも、修正するために#7294に依存しています。 プラス面として、報告されるこれらすべてのJSXの問題を修正するために必要な根本的な変更は同じです。

コンテキストとして、次のようなタイプを効果的に製造します。

declare const JsxSigs: {[K in keyof JSX.IntrinsicElements]: ((props: JSX.IntrinsicElements[K]) => JSX.Element)}[keyof JSX.IntrinsicElements];

これは、最終的には大量の固有の署名の結合になります。

すべての組み込みjsxタグの和集合に変更する前は、それは_just_ string | ComponentType<any> 、これはさらにひどいものでした。

はい、特に3.2より前のバージョンでは、タグにstringタイプを入力すると、タイプチェッカーが静かに_disabled_されます。これは、発行するはずの「インデックスが見つかりません」というエラーが発生しなかったためです。

この問題は重複としてマークされており、最終日にはアクティビティが発生していません。 自動ハウスキーピングの目的で閉鎖されています。

関連する可能性のある問題が発生しました。 私は次のコンポーネントを持っています:

function MaybeLabel(props: { useLabel: boolean }) {
   const { useLabel } = props;
   const TagName = useLabel ? 'label' : 'div';

   return <TagName>Woookie</TagName>
}

その結果

error TS2604: JSX element type 'TagName' doesではなくhave any construct or call signatures.

一方

function MaybeLabel2(props: { useLabel: boolean }) {
   const { useLabel } = props;
   const TagName = useLabel ? 'span' : 'div';

   return <TagName>Woookie</TagName>
}

typescriptコンパイラには完全に受け入れられます。 そのまま:

export function MaybeLabel3(props: { useLabel: boolean }) {
    const { useLabel } = props;
    const TagName = useLabel ? 'label' : 'div';

    return React.createElement(TagName, 'Wookie')
}

MaybeLabel2の唯一の違いは、 label代わりにspanを使用していることです( span代わりにdivも許容できるようです)。 MaybeLabel3は、 MaybeLabelコンパイルされるものとまったく同じであるため、さらに奇妙になります。

@ types / reactおよび@types / react-domの最新バージョンを使用し、typescript 3.2.1、3.2.2、および3.3.0-dev.20181219で問題を検証しました。 3.1.6では、すべて期待どおりに機能します(どの例でもエラーは発生しません)

私にとっての解決策は次のとおりです。

export type WrapperProps = {
    mainApp: React.ElementType
}

@ TacB0sS詳しく説明してください。

スレッドを誤解したかもしれませんが、jsx要素への参照を別のjsx要素に渡したいと思いました。

export const AppWrapper = hot(module)((props: WrapperProps) => {

    const MainApp = props.mainApp;
    if (!MainApp)  // <-- JSX elements MUST start with upper case!!
        throw new ImplementationMissingException("mainApp was not specified!!");

    return (
        <Router history={BrowserHistoryModule.getHistory()}>
            <MainApp prop1={"value"}/>
        </Router>)
});

一緒に:

export type WrapperProps = {
    mainApp: React.ElementType<{prop1:string}>
}

@ TacB0sS私にとっての主なトリックは、 if条件を追加することReact.ComponentTypeReact.ElementTypeどちらを使用してもかまいません。

私はこれの結果を理解しているかどうかわかりません。 解決できなかった同様のエラーがあります。 これが私のユースケースです:

// Logo.tsx

import classNames from 'classnames';

interface Props extends React.HTMLAttributes<HTMLElement> {
  tag?: React.ReactType;
}

const Logo: React.SFC<Props> = props => {
  const { tag: Tag = 'div', className, ...rest } = props;
  return (
    <Tag
      className={classNames(styles.logo, className)}
      {...rest}
      dangerouslySetInnerHTML={{ __html: logo }}
    />
  );
};

そして、私はそれを次のような別のコンポーネントでそのように使用しています:

const Header: React.SFC<{}> = () => {
  return (
    <div>
      <Logo tag="h1" aria-label="Syn By Design: Eric Masiello's Portfolio" />
      Header online
    </div>
  );
};

コンパイラを実行すると、次のエラーが発生します。

components/Logo.tsx:13:6 - error TS2604: JSX element type 'Tag' does not have any construct or call signatures.

13     <Tag
        ~~~


Found 1 error.

これを機能させる方法はありますか?

代わりのComponent 、使用ComponentClass

デフォルトをインポートしたが、対応するエクスポートをデフォルトではなく名前付きとして.d.tsファイルで宣言したため、このエラーが発生しました...しばらく混乱しました

これをここに追加したかっただけです。 これがすでに言われているかどうかはわかりませんが、雇用者注文コンポーネントを実行している場合は、タイプReact.ComponentTypeを使用します。

。 " https://flow.org/en/docs/react/types/#toc -react-componenttype"

@ericmasiello動的に渡されるコンポーネントにReact.ElementTypeを使用することになりました。 私のユースケースは基本的に次のとおりです。

type Props = {
    heading: React.ElementType
}
const Header: FC<Props> = props => {
    const Header = props.heading ?? 'h2';
    return (
        <Header className="some-class"><children /></Header>
    )
}

@ericmasiello動的に渡されるコンポーネントにReact.ElementTypeを使用することになりました。 私のユースケースは基本的に次のとおりです。


type Props = {

    heading: React.ElementType

}

const Header: FC<Props> = props => {

    const Header = props.heading ?? 'h2';

    return (

        <Header className="some-class"><children /></Header>

    )

}

涼しい! どのバージョンのTypescriptとどのバージョンの@types / reactをインストールしましたか?

@ericmasiello

涼しい! どのバージョンのTypescriptとどのバージョンの@types / reactをインストールしましたか?

[email protected]
@ types / react @

私はこれらの2つのことのいずれかを行うことによってこの問題を解決しました:

ケース1:

.d.tsファイル:

declare module "foo" {
   interface PropFoo {
      propy: string;
   }

   class MyTypedComponent extends React.Component<PropFoo> { }
}

反応:

import MyTypedComponent from "foo";

function AnotherComponent() {

   /* Notice in here we have to use the dot operator and reference the component */
   return <MyTypedComponent.MyTypedComponent /> 
}

新しく型付けされたコンポーネントを使用するには、_MyTypedComponent.MyTypedComponent_を記述する必要があることに注意してください。 これは一部の人には明らかかもしれませんが、インポートでドット演算子を使用してコンポーネントを参照するだけで、多くの時間を無駄にしました。

ケース2 [ケース1の別の書き方]:

.d.tsファイル:

declare module "foo" {
   interface PropFoo {
      propy: string;
   }

   export default class MyTypedComponent extends React.Component<PropFoo> { } //Notice the export default in here
}

反応:

import MyTypedComponent from "foo";

function AnotherComponent() {

   /* Since this component is default exported, no need to use the dot operator */
   return <MyTypedComponent /> 
}

基本的に、エクスポート、デフォルトのエクスポート、およびインポートをチェックして、正しく参照していることを確認してください。

私の英語は大変申し訳ありません。これがお役に立てば幸いです。

私にとっての解決策は次のとおりです。

export type WrapperProps = {
  mainApp: React.ElementType
}

niu b

このページは役に立ちましたか?
0 / 5 - 0 評価