2017-10-25 9 views
3

私はReactプロジェクトでTypescriptを使用しようとしていますが、HOCが機能するための型を取得するのに苦労しています。ここで私はとのトラブルを抱えています何披露する最小限の例です。Typescriptより高次のコンポーネントがデコレータとして

const withDecorator = 
    (Wrapped: React.ComponentType): React.ComponentClass => 
     class withDecorator extends Component { 
      render() { 
       return <Wrapped {...this.props} /> 
      } 
     } 

@withDecorator 
class Link extends Component<object, object> { 
    render() { return <a href="/">Link</a> } 
} 

これはエラーを返します:

'Unable to resolve signature of class decorator when called as an expression. 
Type 'ComponentClass<{}>' is not assignable to type 'typeof Link'. 
    Type 'Component<{}, ComponentState>' is not assignable to type 'Link'. 
    Types of property 'render' are incompatible. 
     Type '() => string | number | false | Element | Element[] | ReactPortal | null' is not assignable to type '() => Element'. 
     Type 'string | number | false | Element | Element[] | ReactPortal | null' is not assignable to type 'Element'. 
      Type 'null' is not assignable to type 'Element'.' 

このエラーが発生した理由を、私は本当に理解していません。私は間違ったことをする必要があります。私が小道具を導入すると、事態はさらに毛がいっぱいになります。

私は正しいソリューションを高く評価したいと思いますが、なぜこのエラーが最初に発生するのかを理解することにも非常に興味があります。

ありがとうございます!値を返す

答えて

2

クラスデコレータは入力と同じタイプを有するようにデコレータの戻り値を

const Link = withDecorator(class extends Component<object, object> { 
    render() { 
     return <a href="/">Link</a> 
    } 
    instanceMethod() { return 2 } 
    static classMethod() { return 2 } 
}) 

活字体を期待することと同様であるので、結果は同じ挙動を有します。あなたの例ではは、レンダリング型シグネチャが一致していませんが、追加されたメソッドでの問題は、より明らかである。デコレータの実装で、次は失敗します:

new Link().instanceMethod() 
Link.classMethod() 

正しい型シグネチャは次のようになります。

function withDecorator<T extends React.ComponentClass>(Wrapped: T): T 

と実装は、ターゲットクラスを拡張することによって最も簡単に、あまりにも一致している必要があります:

return class extends Wrapped { ... } 

注意をREACとのことあなたは必ずしもクラスを拡張したくないので、デコレータを使うのはおそらく最善の解決策ではないでしょう。

も参照してください。https://github.com/Microsoft/TypeScript/issues/9453

+0

ありがとうございます!私は、クラスのシグネチャを変更する関数を持つクラスをラップするための構文的な砂糖としてデコレータを考えていたと思います。私はそれがいくつかの図書館でそのように使われているのを見ますが、Typescriptはデコレータがどのように機能するかについてより慎重な意見を持っています。 – genuinelycurious

関連する問題