2017-06-07 61 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 – 2017-06-07 07:30:08

回答

6

如果定義

type FAs = [Function, {}]; 

然後FAs類型的值將需要Function型的第一元件,{}型的第二元件,以及​​後續的元件。這就是TypeScript文字數組類型的工作原理。從TS docs

當訪問組已知指標以外的元素,聯合類型來代替:

這應該做你想要一切除了的事實,你會能夠傳遞一個Function -type值作爲數組的第三個元素等。但實際上無論如何都會是這種情況,因爲Function{}兼容。

有沒有辦法解決這個問題。 TS中沒有辦法定義一個陣列類型,其中第一個元素是某些特定類型的元素,並且有任意數量的其他特定類型的其餘元素。

我也懷疑類型系統是否支持可以說是任意長度的元組。

實際上,類型系統只有支持任意長度的元組。如果你說

type Tuple = [number, number]; 

這種類型是長約兩或更大,包含數字與任何兼容陣列。如果你說

type Tuple = [string, number]; 

這種類型與任何陣列兼容,長度的兩個或更長,具有字符串作爲其第一元件,一個數字作爲其第二,和一個字符串或數字作爲它的第三等等。我不會說這種行爲的原因是「基於計算機科學」。更重要的是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

我很肯定這是Typecript 2.3中最好的。例如,你可以在lodash中看到類似這樣的類型。

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

這是我的想法,也有,但是打字稿的使用工會打字的元素沒有特別定義是非常有幫助的。請參閱接受的答案以獲得絕佳的描述以及一個重要的警告。 – anticrisis

+0

你說得對,如果你不需要嚴格的打字,這會很有幫助。我想我已經離開了,並沒有對你的問題非常關注:) – dbandstra

相關問題