2017-07-30 70 views
7

與函數的參數推斷我有map功能:隱式類型的打字稿

const map = <T, U>(f: (x: T) => U, arr: T[]): U[] => { 
    return arr.map((val) => f(val)); 
} 

當我打電話map用匿名函數作爲回調,它的返回類型是正確的:

// `x1` variable type here is { name: string }[], which is correct 
const x1 = map(x => x, [{name: 'John'}]); 

但當我提供identity函數而不是匿名函數時,返回類型是錯誤的:

const identity = <T>(x: T) => x 
// return type of `x2` is {}[] here 
const x2 = map(identity, [{name: 'John'}]); 

如何爲第二個示例獲取正確的類型結果,而不提供map函數的顯式類型參數?

+1

如果你在'identity'上指定返回類型爲'T',該怎麼辦? – jonrsharpe

+0

@jonrsharpe得到相同的結果。 – 1ven

+2

如果您切換map()參數的順序,它可以正常工作。我想它迫使編譯器首先匹配數組元素類型?我不知道是否有辦法讓推理按照您的順序進行。 – jcalz

回答

2

經過一番嘗試,我真的懷疑TypeScript能夠跟得上你。 例如:

const x4 = map(identity, [2]); 
// x4 is '{}[]' 

這是obviosly甚至比你的例子更是錯誤的。

其他一些測試:

const x2 = map(<({ name: string }) => { name: string }>identity, [{ name: 'John' }]); 
// x2 is '{ name: string }[]' 

和:

const double = (x: number) => 2 * x; 
const x3 = map(double, [2]); 
// x3 is 'number[]' 

這讓我得出這樣的結論打字稿就不能打破所有泛型到一個有意義的類型,只是說:{}