2017-06-07 12 views
7

最初の要素が特定の型(たとえばFunction)である配列の型を定義したいと思います。空のタイプ。例:Typescriptでは、最初の要素が残りよりも具体的な配列の型を定義します。

type FAs = [Function, {}, {}, {}, ...]; // pseudo code 

このようなことは可能ですか?

目的は、このように、単一の引数の機能を提供することです:

const myCaller = ([fun, ...args]: FAs) => fun.apply(args); 

別のアプローチは、このように、myCallerに二つの引数を使用することです:

const myCaller = (fun: Function, args: any[]) => fun.apply(args); 

が、審美的な理由で私は単一の議論を使用することを好むだろう。私はまた、型システムがおそらく任意の長さのタプルをサポートしているのだろうかと思います。たぶん、そのようなことは私が理解していないコンピュータサイエンスの理由から望ましくないかもしれません。

+0

やや関連:https://github.com/Microsoft/TypeScript/issues/212 –

答えて

6

もし

type FAs = [Function, {}]; 

を定義する場合、タイプFAsの値はタイプFunctionの最初の要素、種類{}の第2の要素、及び​​の後続の要素を必要とします。これがTypeScriptのリテラル配列型の仕組みです。 TS docs

知られているインデックスのセット外の要素にアクセスし、労働組合のタイプが代わりに使用されます。これは、あなたがあるという事実のために除いて、あなたがを望むすべてを行う必要があります

配列の3番目の要素などとして型付きの値Functionを渡すことができます。しかし、実際にはそれはとにかくケースです。Function{}と互換性があるからです。

これを回避する方法はありません。 TSには、最初のn要素がある特定の型であり、他の特定の型の残りの要素が任意の数である配列型を定義する方法はありません。

また、型システムがおそらく任意の長さのタプルをサポートしているのか疑問です。

実際には、タイプシステムは、任意の長さのタプルをサポートしています。あなたは

type Tuple = [number, number]; 

を言うなら、このタイプは数字が含まれている長さ2 以上の任意の配列、と互換性があります。もし

type Tuple = [string, number]; 

を言う場合、このタイプは、その第三のように、その最初の要素として文字列、その第二のような数、文字列または数字のいずれかを有し、長さ2 以上の任意の配列、と互換性があります私はこの行動の理由を「コンピュータサイエンスベース」と呼ぶことはしません。それはTSがチェックすることが可能であることのより多くの問題です。

代替アプローチ

interface Arglist { 
    [index: number]: object; 
    0: Function; 
} 

const a1: Arglist = [func]; 
const a2: Arglist = [22];     // fails 
const a3: Arglist = [func, "foo"];   // fails 
const a4: Arglist = [func, obj]; 
const a5: Arglist = [func, obj, obj]; 
+0

Typescriptは、そのドキュメントページを何度も読んだにもかかわらず、既知のインデックスのセットの外側にある要素には、共用体型を使用します。明確な説明とドキュメントへのリンクをありがとうございます。 – anticrisis

0

私はこれがTypescript 2.3の中でできることは最高だと確信しています。たとえば、ロダッシュのような入力を見ることができます。

interface IMyCaller { 
    <R>([fn]: [() => R]): R; 
    <R,A>([fn, a]: [(a: A) => R, A]): R; 
    <R,A,B>([fn, a, b]: [(a: A, b: B) => R, A, B]): R; 
    <R,A,B,C>([fn, a, b, c]: [(a: A, b: B, c: C) => R, A, B, C]): R; 
    // keep adding these until you get tired 
} 

const myCaller: IMyCaller = ([fun, ...args]) => fun.apply(args); 
+0

また、これは、私が考えたものですが、特に要素ではないために組合タイピングの活字体の使用定義は非常に有用です。 1つの重要な注意書きとともに、優れた説明については受け入れられた回答をご覧ください。 – anticrisis

+0

厳密な入力が必要ない場合は役立ちます。私は逃げ出してあなたの質問に非常に細心の注意を払っていないと思います:) – dbandstra

関連する問題