[英]Why does TypeScript not infer types for some piped functions?
2月28日更新:關閉該問題,轉而支持新問題。
在下面的代碼片段中,如果查看最后兩行,TypeScript會在第一行中顯示錯誤,並在第二行中正確推斷類型,盡管差異只是函數通過管道傳遞的順序。
const pipe = <A, B, C>(
x: A,
a: (x: A) => B,
b: (x: B) => C,
) => b(a(x));
// This just calls the function passed as argument.
const call = <A, B>(f: (x: A) => B) => (x: A) => f(x)
const a = pipe(1, x => x + 1, call(x => x + 1));
const b = pipe(1, call(x => x + 1), x => x + 1);
我在嚴格模式下使用TypeScript 2.7.1(包括strictFunctionTypes),但嚴格模式似乎並不重要。 這是TypeScript操場上的這個片段 。
這是我在使用RxJS時遇到的一個問題,因為在RxJS中有一個類似的pipe
方法,我在使用創建運算符時傳遞箭頭函數(如obs => merge(obs, otherObs)
)。 通常通過指定參數類型很容易解決這個問題,但我想了解這背后的邏輯。 為什么TypeScript能夠在一種情況下推斷出類型但在另一種情況下卻不能推斷?
這個問題仍然很突出,但是現在我想發布一個我想出的解決方法,因為我發現它在我的經驗中非常有用。
創建這樣的實用程序函數:
export const call = <A, B>(f: (x: A) => B) => f;
(與問題中的函數相同,一個將一元函數作為參數的標識函數),然后每當您在管道中遇到箭頭函數的問題時,請嘗試使用此實用程序函數將其括起來。 違反直覺,TS不能處理這個問題:
const a = pipe(1, x => x + 1, call(x => x + 1));
但它可以處理這個:
const c = pipe(1, call(x => x + 1), call(x => x + 1));
(不知道為什么)。 稍后當問題得到解決時(請繼續進行操作: https : //github.com/Microsoft/TypeScript/issues/22081 ),您將能夠輕松找到所有call
引用並將其刪除。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.