web-dev-qa-db-ja.com

ジェネリックReact TypeScript / JSXのコンポーネント?

プラグ可能なReactコンポーネントを作成したい。コンポーネントはクラス名によって解決されるので、当然ジェネリックに惹かれますが、これは機能しないようです。

class Div<P, S, C extends React.Component> extends React.Component<void, void> {

    render() {
        return (
            <div>
                <C /> // error: Cannot find name 'C'.
            </div>
        );
    }
}

プラグ可能なTypeScriptコンポーネントを作成する別の方法はありますか?

12

これはジェネリックを使用して行うことはできませんが、通常のpropsメカニズムを使用して内部要素を提供するだけでなく、この問題にジェネリックを使用する理由は明確ではありません。

その理由は、型が消去されるため、クラスコンストラクターをクラスに提供して、Cでインスタンス化する値への参照を持つようにする必要があるためです。ただし、JSX props(またはstateまたは必要なこと)以外に、その値を渡す場所はありません。

言い換えれば、書く代わりに

_// not sure what you would expect the syntax to be?
const elem = <Div<Foo> ... />; 
_

あなたは書くべきです

_const elem = <Div myChild={Foo} />
_

renderでそれを次のように消費します

_const Child = this.props.myChild;
return <div><Child /></div>;
_

余談ですが、正しい制約は_React.Component_ではなくnew() => React.Componentです。JSXで記述したもの(_<Div>_など)はコンストラクタークラスではなく、クラスインスタンス

11
Ryan Cavanaugh

TypeScriptタイプが消去されているため、この質問に対する受け入れられた答えはまだ残っていますが、TypeScript 2.9以降、 一般的なJSXコンポーネントがサポートされています

提供される例は次のとおりです。

class GenericComponent<P> extends React.Component<P> {
    internalProp: P;
}
type Props = { a: number; b: string; };

const x = <GenericComponent<Props> a={10} b="hi"/>; // OK
const y = <GenericComponent<Props> a={10} b={20} />; // Error

質問のタイトルでここにたどり着いた人には、言及する価値があると思っただけです。

16
Jono Job