簡體   English   中英

為什么TypeScript不推斷某些管道函數的類型?

[英]Why does TypeScript not infer types for some piped functions?

更新2018年2月20日: 在GitHub上發布此問題

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM