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.
これには残りのエラーメッセージがありませんが、確かに、最新バージョンの@types/react
を使用していて、node_modulesまたはロックファイルに重複が残っていないことを確認してください。
編集:あなたはおそらくReactTypeではなくComponentTypeを使用することを意味します
@Kovensky
私は必ず、最新の使用して作成してもらってください@types/react 16.7.7
と重複なし@types/react
でyarn.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
A
とB
は同じタイプであるため、この動作は完全に無効であると思いB
とD
は_類似したタイプ_がありますが、 D
は割り当てられません🤔
リポジトリ内のコード: https :
const
を使用しているため、そうではありません。 A
のタイプはtypeof configEmpty.ElementType
ですが、 B
のタイプは'div'
です。 let
を使用すると、両方で同じ動作が表示されます。
@Kovensky A
とC
どうですか? なぜ、 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
A
とB
は明らかに定義されたタイプが同じですが、なぜ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.ComponentType
とReact.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つのことのいずれかを行うことによってこの問題を解決しました:
.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_を記述する必要があることに注意してください。 これは一部の人には明らかかもしれませんが、インポートでドット演算子を使用してコンポーネントを参照するだけで、多くの時間を無駄にしました。
.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
最も参考になるコメント
私にとっての解決策は次のとおりです。