シナリオは次のとおりです。
カスタムコンポーネントがあります:
class MyComponent extends React.Component {
render () {
return (
<SuperComponent>
<SubComponent1 /> // <- valid child
</SuperComponent>
)
}
class MyComponent extends React.Component {
render () {
return (
<SuperComponent>
<SubComponent2 /> // <- No! It's not right shape
</SuperComponent>
)
}
参照されるSuperComponentとSubComponent1は次のとおりです。
interface superPropsType = {
children: ReactElement<subPropsType1>
}
class SuperComponent extends React.Component<superPropsType> { ... }
interface subPropsType1 = {
name: string
}
class SubComponent1 extends React.Component<subPropsType1> { ... }
interface subPropsType2 = {
title: string
}
class SubComponent2 extends React.Component<subPropsType2> { ... }
SubComponent1をSuperComponentの唯一の有効な子にしたい、つまり、<SubComponent2 />
またはその他のタイプを<SuperComponent>
の子として配置した場合にTypeScriptがエラーをスローできるようにしたい。
TypeScriptはの子がReactElementのタイプである必要があることだけをチェックしているようですが、tsはその子(subPropsType1)の小道具の形状をチェックしません。つまり、文字列または数値をSuperComponentの子として配置した場合です。 、tsは、型の要件が満たされていないことを訴えますが、ここにjsxタグ(ReactElementにトランスパイルされます)を配置すると、tsはサイレントになります
何か案が ?また、ここに投稿するために設定が必要な場合は、遠慮なく質問してください
アイデアと解決策に本当に感謝します
TypeScript 3.1以降、すべてのJSX要素はJSX.Element
タイプを持つようにハードコードされているため、特定のJSX要素を受け入れる方法はなく、他の要素を受け入れる方法はありません。この種のチェックが必要な場合は、JSX構文を放棄し、React.createElement
をラップするが、コンポーネントタイプごとに異なる要素タイプを返す独自の要素ファクトリ関数を定義し、そのファクトリ関数への呼び出しを手動で書き込む必要があります。
TypeScriptがファクトリ関数の実際の戻り値の型に基づいてJSX要素に型を割り当てるための オープンな提案 があります。これはTypeScript 3.2(2018年11月下旬にリリース予定)と同時に実装される可能性があります。特定のコンポーネントタイプに対して。それが実装されると、React.createElement
をラップする独自のファクトリ関数を定義し、それをjsxFactory
コンパイラオプションで指定できるようになり、追加の型情報を取得できます。または、機能を気にしないプロジェクトに悪影響を与えることなく実行できる場合は、@types/react
が変更されてReact.createElement
がより豊富な型情報を提供するようになるかもしれません。私たちは待って見る必要があります。
私はおそらくSuperPropsType.children
を次のように宣言します。
children: React.ReactElement<SubPropsType1> | React.ReactElement<SubPropsType1>[];
単一の子と複数の子の両方を持つ可能性を説明するため。
いずれにせよ、すでに指摘したように、それは期待どおりに機能しません。
代わりにできることは、小道具を宣言することです。たとえば、subComponentProps: SubPropsType1[]
を宣言して、JSXではなくSubComponent1
を作成し、SuperComponent
内にレンダリングするために必要な小道具を渡します。
interface SuperPropsType {
children?: never;
subComponentProps?: SubPropsType1[];
}
...
const SuperComponent: React.FC<SuperPropsType> = ({ subComponentProps }) => {
return (
...
{ subComponentProps.map(props => <SubComponent1 key={ ... } { ...props } />) }
...
);
};