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'に割り当てることができません。
T
はstring
として推論されるか、またはT=string
in <Selector>
。解決策はありますか?
私が見つけた唯一の回避策は、コンポーネントを拡張してすべての型引数を排除することです:
class StringSelector extends Selector<string> { }
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
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>
私は会社で作成したコンポーネントで機能するジェネリックを取得しましたが、なんとか実現できませんでした。
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
これを試して。インターフェースは、期待する値のタイプを明示的に宣言する必要があります。 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, {}> {
// ...
}