web-dev-qa-db-ja.com

JSXノードのTypeScript型引数

JSXでレンダリングされたコンポーネントの型引数を指定する方法はありますか?

たとえば、次のコンポーネントについて考えます。

interface SelectorProps<T> {
    selection: T;
    options: T[];
}

class Selector<T> extends React.Component<SelectorProps<T>, {}> {
    // ...
}

このコンポーネントをJSXでレンダリングしようとすると、次のようになります。

<Selector selection="a" options={["a", "b", "c"]} />

私はこれらのエラーを受け取ります:

TS2322:タイプ 'string'はタイプ 'T'に割り当てることができません。

TS2322:タイプ 'string []'はタイプ 'T []'に割り当てることができません。タイプ 'string'はタイプ 'T'に割り当てることができません。

Tstringとして推論されるか、またはT=string in <Selector>。解決策はありますか?

私が見つけた唯一の回避策は、コンポーネントを拡張してすべての型引数を排除することです:

class StringSelector extends Selector<string> { }
12
Aaron Beall

https://github.com/Microsoft/TypeScript/issues/6395 で説明されている一般的なJSX要素がサポートされるようになりました-TypeScript 2.9以降。

これで次のことができるようになります。

 <Selector<string> selection="a" options={["a", "b", "c"]} />

参照: http://www.typescriptlang.org/docs/handbook/release-notes/TypeScript-2-9.html

20
Philip
interface FooProps<T> { foo: T; }
class Foo<T> extends React.Component<FooProps<T>, any> {
  render() {
    return <div>{ JSON.stringify(this.props.foo) }</div>;
  }
}
type FooBar = new () => Foo<{bar: string}>;
const FooBar = Foo as FooBar;

class FooBarContainer extends React.Component<any, any> {
  render() {
    return <FooBar foo={{bar: 'works'}} />;
  }
}

FooBarContainerまたは<FooBar foo={{bar: 'works'}} />はレンダリングする必要があります:<div>{"bar":"works"}</div>

2
StrikeForceZero

私は会社で作成したコンポーネントで機能するジェネリックを取得しましたが、なんとか実現できませんでした。

GenericComponent.tsx:

import * as React from "react";

interface IGenericComponentProps<T, S> {
    propT: T;
    propS: S;
}

interface IGenericComponentState<T, S> {}

export class GenericComponent<T, S> extends React.Component<
    IGenericComponentProps<T, S>,
    IGenericComponentState<T, S>
    > {
    public render(): JSX.Element {
        return (
            <div>Generic component!</div>
        );
    }

}

export default GenericComponent;

GenericComponentImplementation.tsx:

import * as React from "react";

// This is the ugly part
import GenericComponentBase from "./GenericComponent";
// This is where you get to define the generic type arguments
interface StringAndNumberComponentBase { new (): GenericComponentBase<string, number>; };
const StringAndNumberComponent = GenericComponentBase as StringAndNumberComponentBase ;

export default (): JSX.Element => {
    return (
        <StringAndNumberComponent
            propT="test"
            propS={2}
            />
    );
};

私はこの時にこのgithubの問題からこの情報を得たと思います: https://github.com/Microsoft/TypeScript/issues/396

0
Alexander

これを試して。インターフェースは、期待する値のタイプを明示的に宣言する必要があります。 TypeScriptを使用することの要点は以上です。何を期待するのか本当にわかっている場合は、何も推測しないでください。

interface SelectorProps {
    selection: string | number; // This means selection can take in either a string or a number
    options: string[] | number[];
}

class Selector extends React.Component<SelectorProps, {}> {
    // ...
}
0
Edwin Kato