2017-08-15 4 views
1

オーバーロードされた関数シグネチャの型エイリアスを作成することはできますか?私は繰り返しを保存するために、その過負荷に署名するタイプのエイリアスを作成したい、と私はのタイプを記述する必要がある他の場所での使用になるだろうTypeScript:オーバーロードされた関数シグネチャの型エイリアスを提供できますか?

function whenChanged(scope: ng.IScope, fn:()=>void):()=>void; 
function whenChanged(fn:()=>void, truthy:any):()=>void; 
function whenChanged(a,b):()=>void { 
    //... 
} 

例えば、私のような機能を持っていますこの関数。

私が試した:

type WC1 = (scope: ng.IScope, fn:()=>void) =>()=>void; 
type WC2 = (fn:()=>void, truthy:any) =>()=>void; 
type WhenChanged = WC1 | WC2; 

const whenChanged: WhenChanged = (a,b) => { 
    //... 
}; 

しかし、この機能を使用しようと、私は「そのタイプのコールサインを欠い表現を呼び出すことはできません」の線に沿ってエラーが発生します。

タイプエイリアシング機能のオーバーロードについては、ドキュメントには何も表示されません。

答えて

1

すでに機能whenChanged持っているので:

function whenChanged(scope: ng.IScope, fn:()=>void):()=>void; 
function whenChanged(fn:()=>void, truthy:any):()=>void; 
function whenChanged(a,b):()=>void { 
    //... 
} 

をその型用の型のエイリアスを取得する最も簡単な方法はtypeoftype queryを使用することです:

type WhenChanged = typeof whenChanged; 

次に、タイプエイリアスを作成する最も簡単な方法は、overloaded function signature(これはwhあなたは)探していた時:

type WhenChanged = { 
    (scope: ng.IScope, fn:() => void):() => void; 
    (fn:() => void, truthy: any):() => void; 
} 

(あなたのエディタでtypeof定義の上にマウスを置く場合は、quickinfoに表示される内容である)「あなたはドン場合はinterfaceを使用する必要がないことに注意してください。欲しい。あなたができる


次のことは、あなたがやっていたものに似ていますが、問題は、過負荷が交差点、ない組合であるということです。それは両方の署名です:

type WC1 = (scope: ng.IScope, fn:()=>void) =>()=>void; 
type WC2 = (fn:()=>void, truthy:any) =>()=>void; 
type WhenChanged = WC1 & WC2; // and, not or 

は、彼らが過負荷を表し、具体的ので、そのintersections of function signatures are not commutative注意してください。それは次のタイプが技術的には同じではないことを意味します

type NotWhenChanged = WC2 & WC1; // different type 

オーバーロードの解決が異なる順序で行わからです。

WC1またはWC2であるかどうかをコンパイラーが判別できないため、タイプがWC1 | WC2の関数を呼び出すことはできません。


よろしくお願いします。それが役に立てば幸い;がんばろう!

+0

これは素晴らしい答えです。まさに私が何をしたのか!ありがとうございました! – jsdw

1

再生した後、答えが(少なくとも部分的に)インターフェイスを使用していることが分かります。これが動作しているようです:

interface WhenChanged { 
    (scope: ng.IScope, fn:()=>void):()=>void 
    (fn:()=>void, truthy:any):()=>void 
} 

const whenChanged: WhenChanged = (a,b) => { 
    //... 
}; 
+0

私は、関数が両方の必要な型のシグネチャに一致する場合にのみ機能することがわかります。したがって、 'a'を' scope:ng.IScope'に変更すると 'IScope'は'()=> void'と互換性がないため、拒否します。 – Duncan

+0

'interface'ではなく' type'を使うことができます。詳細は私の答えを参照してください – jcalz

0

種類の労働組合が呼び出すことはできませんを意味し、あなたが一種類か一方を選択しなければならない「とは、そのタイプのコールサインを欠い表現を呼び出すことはできません」。

問題は一例で、あなたがabのための型を定義していないので、コンパイラは、実際に使用されているWC1WC2のどの伝えることができない与えたことです。あなたがwhenChangedの定義を変更した場合:

const whenChanged: WhenChanged = (a: ng.IScope, b:()=>void) => { 
    return b; 
}; 

今コンパイラが、それはあなたが安全にそれを呼び出すことができwhenChangedWC1の種類を制限することができます知っています。

場合は、変数を持っていたし、あなたが呼び出す前に、どちらか一方に種類を制限するために型アサーションのいくつかの種類を使用する必要がありますwhenChangedは、言うことができない方法でWC1またはWC2コンパイラのいずれかである可能性が代わりのconstのそれ:

(whenChanged as WC1)(some_scope, some_fn); 

か:あなたが行うことができない何

(whenChanged as WC2)(some_fn, some_truthy); 

はそれが適切な引数でそれを呼び出すために含まれているタイプwhenChangedからうまくあります。他の場所からその情報を取得する必要があります。

+0

jsdwは実際に関数型の和集合を呼び出そうとしていません。問題は、オーバーロードされた関数のシグネチャに関するものです.jsdwの試みは、交点が適切であった場合にユニオンを使用することでした。 – jcalz

関連する問題