2017-04-13 1 views
0

ユーザーが認証されているかどうかを確認するために高次コンポーネントを作成しようとしています。私は15.5.4に反応使用し、タイプ@/15.0.21を反応させて、次のように私の(簡体字)のコードが見えますよ:型保証された上位コンポーネントクラスコンポーネントとステートレス機能コンポーネントに対する反作用コンポーネント

TS2345:Argument of type 'ComponentClass<Props> | StatelessComponent<Props>' is not assignable to parameter of type 'ComponentClass<Props>'. 
    Type 'StatelessComponent<Props>' is not assignable to type 'ComponentClass<Props>'. 
    Type 'StatelessComponent<Props>' provides no match for the signature 'new (props?: Props | undefined, context?: any): Component<Props, ComponentState>' 

import * as React from 'react'; 

interface IAuthProps { 
    authenticated: boolean 
} 

function authenticated1<Props extends Object>(wrapped: React.ComponentClass<Props> | React.SFC<Props>): 
    React.SFC<Props & IAuthProps> { 
    return (props: Props & IAuthProps): React.ReactElement<any> => { 
    if (props.authenticated) { 
     return React.createElement(wrapped, props); 
    } else { 
     return <h1>Unauthorized!</h1> 
    } 
    } 
} 

はしかし、コンパイルはcreateElementへの呼び出しに失敗しました

@types/reactがオーバーロードされた関数としてReact.createElementを宣言し、Typescript can't resolve overloads with union typesを宣言しているので、このエラーは驚くことではありません。

しかし@types/reactSFCEelementは、戻り値の型に互換性があるので、ReactElementを継承)労働組合の各タイプの対象とオーバーロードを提供します。

function createElement<P>(
    type: ComponentClass<P>, 
    props?: Attributes & P, 
    ...children: ReactNode[]): ReactElement<P>; 

function createElement<P>(
    type: SFC<P>, 
    props?: Attributes & P, 
    ...children: ReactNode[]): SFCElement<P>; 

私はちょうど検討する活字体を強制する必要があると思い、コードのコンパイルを行うにはいずれかのユニオン型の対応する分岐のオーバーロードが、私はそれを行う方法がわかりません。

ComponentClassSFCを区別して、Typescriptでタイプチェックに対応するオーバーロードを選択するにはどうすればよいですか?


PS:現在、私はちょうど私はむしろないと思い、両方のオーバーロードは、両方の引数の型を受け入れる同じランタイム関数を呼び出すので、安全であるwrapped as React.ComponentClass<Props>を渡すことで、最初のオーバーロードを選択することを強制的に、しかしですここでは "チート"のように、代わりにタイプシステムが安全を保証するようにしてください。

答えて

0

タイプ定義を変更する必要があるため、現在はできません。

オブジェクトのタイプを絞り込むことができるタイプガード機能を使用するには、定義を少し拡張する必要があります。

interface StatelessComponent<P> { 
    (props: P & { children?: ReactNode }, context?: any): ReactElement<any>; 
    type: 'StatelessComponent'; // NEW ONE 
    propTypes?: ValidationMap<P>; 
    contextTypes?: ValidationMap<any>; 
    defaultProps?: Partial<P>; 
    displayName?: string; 
} 

interface ComponentClass<P> { 
    new (props?: P, context?: any): Component<P, ComponentState>; 
    type: 'ComponentClass'; // NEW ONE 
    propTypes?: ValidationMap<P>; 
    contextTypes?: ValidationMap<any>; 
    childContextTypes?: ValidationMap<any>; 
    defaultProps?: Partial<P>; 
    displayName?: string; 
} 

そして、我々はdefinitelytypedリポジトリ

にこの問題に関する問題を作成するために、良いアイデアかもしれないということ

function createElementWrapper<Props extends Object>(wrapped: React.ComponentClass<Props> | React.SFC<Props>, props: any) { 
    if (wrapped.type === "StatelessComponent") { 
    return React.createElement(wrapped, props); // wrapped is a StatelessComponent 
    } else { 
    return React.createElement(wrapped, props); // wrapped is a ComponentClass 
    } 
} 

ような何かを行うことができるだろう

関連する問題