2016-11-17 13 views
3

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

TS2322:

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

が、私はこれらのエラーを取得:タイプを「私はJSXで、このコンポーネントを描画しようとした場合

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

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

たとえば、このコンポーネントを考えます文字列 'はタイプ' T 'に割り当てられません。

TS2322: 'string []'型は 'T []'型に割り当てられません。タイプ 'string'はタイプ 'T'に割り当て可能な ではありません。

私はTstringまたは他<Selector>T=stringを指定するためのいくつかの方法として推論されることを期待します。解決策はありますか?

class StringSelector extends Selector<string> { } 
+2

まだありません。 https://github.com/Microsoft/TypeScript/issues/6395 –

+0

を参照してくださいありがとう、その問題の対象となります。今のところ私の 'extend'回避策に固執するでしょう。 – Aaron

答えて

0

はこれを試してみてください:

私が見つけた唯一の回避策は、すべての型引数を排除するためのコンポーネントを拡張することです。インタフェースは、期待する値の型を明示的に宣言する必要があります。これがタイプスクリプトを使用する全体的なポイントです。何を期待するか本当に知っていれば、何かを推測するべきではありません。

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

それでは、文字列、数字、オブジェクト、その他のさまざまなインターフェースを選択できる 'Selector'をどうやって作るのですか?これは型引数のためのものなので、 'any'のようなあいまいな型を使う必要はありません。 – Aaron

+0

その場合は、ユニオンタイプを使用してください。私の答えを変更してサンプルを表示する@Aaron –

+0

私は既に4種類あり、私のアプリではプリミティブではなく実際のオブジェクトインターフェイスです。組合は、 'selection'が' options'と同じ型であることを明確にしていません。アサーションをコードで記述する必要があります。また、コンポーネントが処理するすべての型を前面から把握する必要があります。型引数は私がここに必要なものですが、唯一の問題はJSXが(まだ)それらを渡す方法を持っていないことです。 – Aaron

0

私は私の会社で作成したコンポーネントで作業ジェネリックをgottonているが、彼らは方法私はそれはきれいではありませんでし行うことができました。

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/3960

1
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>

+1

"foobar" jarbleに従うのはちょっと難しいですが、これは実際に 'extended'を使った私の回避策とは何か違うのですか? – Aaron

関連する問題