2017-07-25 26 views
0

react-trackingのアンビエント宣言を作成中です。それはtrackデコレータを公開しています。このデコレータは、クラスの両方のメソッドで使用できます。多型デコレータ用のTypeScript宣言

ドキュメントから取られた簡単な例:

declare function track(trackingInfo?: any, options?: any): <T>(component: T) => T 
declare function track(trackingInfo?: any, options?: any): any 

export default track 

:私は、次のような何かをして活字体が右のオーバーロードを選ぶ持つことができると期待私の周囲宣言ファイルで

import track from 'react-tracking' 

@track({ page: 'FooPage' }) 
export default class FooPage extends React.Component { 

    @track({ action: 'click' }) 
    handleClick =() => { 
    // ... 
    } 
} 

これはコンポーネントクラスではうまくいくが、次のエラーを伴うメソッドでは失敗する:

[ts] Unable to resolve signature of method decorator when called as an expression. 

デコレータのこのアプリケーションでTSが選択するタイピングを見てみると、それは何かにマッチしなければならないシグネチャに戻るのではなく、コンポーネントクラスのものに落ちていないことを示します。

enter image description here

それがすべてで多型のデコレータを入力することは可能ですか?そしてもしそうなら、私は何が間違っていますか?


更新:ここでは簡略化した例を示します。

最初のものは、単形性であると期待どおりに動作:

function trackClass(trackingInfo?: any, options?: any): ClassDecorator { 
    return null 
} 

function trackMethod(trackingInfo?: any, options?: any): MethodDecorator { 
    return null 
} 

@trackClass({}) 
class Foo { 
    @trackMethod({}) 
    someMethod() {} 
} 

この第二の例では、多型性であり、両方のために失敗:

function track(trackingInfo?: any, options?: any): ClassDecorator | MethodDecorator { 
    return null 
} 

@track({}) 
class Bar { 
    @track({}) 
    someMethod() {} 
} 
+0

第2の例は、あなたが 'ClassDecorator | MethodDecorator' - デコレータが呼び出されたときに "正しいことをする"ため、戻り値の型は 'ClassDecorator&MethodDecorator'です。 –

答えて

1

活字体のlib.d.ts有しClassDecoratorMethodDecoratorタイプ:

2つのいずれかの操作を行います。

interface TrackDecorator { 
    // Class decorator overload 
    <TFunction extends Function>(target: TFunction): TFunction; 

    // Property decorator overload 
    <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>): TypedPropertyDescriptor<T>; 
} 

export default function track(trackingData?: object): TrackDecorator; 
  • が適切に過負荷を結合する型を派生:

    1. は両方と互換性のあるオーバーロードがありタイプを作成します。

      interface TrackDecorator extends ClassDecorator, MethodDecorator { } 
      export default function track(trackingData?: object): TrackDecorator; 
      

    前者は、あなたがより具体的にすることができますが、後者は活字体は心の中でデコレータのために(つまり、スペックが変更された場合、それはそのreact-trackingを暗示されたものは何でもバージョンにあなたを結ぶだろうどちらのバージョンもサポートします)。

  • +0

    これまでのところ、Daniel!私はあなたが言っていることを得るが、実際にそれを働かせる方法をまだ理解できない。'track'関数は、クラスデコレータ関数かメソッドデコレータ関数のどちらかを返します。これらの型のいずれかを返すという問題だけを示した縮小例を使って投稿を更新しました。 – alloy

    +0

    問題が見つかりました。 'dts-gen'を使って新しいDefinitelyTypedパッケージを作成したとき、' tsconfig.json'に 'lib:" es6 "'を設定しましたが、明らかに 'target:" es6 "'が必要でした。今すぐあなたの提案が期待通りに機能し始めました。それが理にかなっている場合は、回答を更新して回答を受け入れることができますか? – alloy

    関連する問題