![](/img/trans.png)
[英]How to define a generic anonymous function type in TypeScript?
[英]in typescript, how to define a specialized version of a generic function?
如果我有一個通用的 function:
const f1 = <T>(x: T) => console.log(x)
我可以為 f1 定義一個專門的版本:
const f2 = (x: number) => f1(x)
然后 typescript 如果我這樣做會拋出一個錯誤:
f2('6')
但 f2 實際上是另一個調用 f1 的 function。
有沒有辦法將 f2 定義為 f1 的專用版本? 就像是:
const f2 = f1<number> // this doesn't work
您可以像這樣定義泛型類型
type Fn<T = any> = (x: T) => void
const f1: Fn = (x) => console.log(x)
const f2: Fn<number> = f1
f2('6') // Argument of type '"6"' is not assignable to parameter of type 'number'.
這是一個工作游樂場的鏈接
我將更改您的示例 function 因為類型<T>(x: T)=>void
對泛型類型參數沒有任何用處,實際上與(x: unknown)=>void
相同,a具體 function 型。 相反,讓我們看一下<T>(x: T)=>T
類型的 function ,它保留輸入類型並輸出相同類型的值,其中(x: unknown)=>unknown
不夠:
const f1 = <T>(x: T) => (console.log(x), x);
// const f1: <T>(x: T) => T
const n: number = 6;
const sixNumber = f1(n); // const sixNumber: number
const s: string = "6";
const sixString = f1(s); // const sixString: string
您要做的是采用通用 function f1
並將其用作(x: number)=>number
類型的具體 function f2
。 這是f1
類型的擴展,因為<T>(x: T)=>T
類型的每個 function 也是(x: number)=>number
類型的 function ,反之亦然。 編譯器將此識別為有效的擴展,您可以自己將f2
注釋為擴展類型:
const f2: (x: number) => number = f1; // no error
const sixNumberOkay = f2(n); // okay
const sixStringNotOkay = f2(s); // error! string is not number
所以這很好。
--
現在,正如您所指出的,您不能做的是采用f1
的類型和類型number
並自動生成f2
的類型。 類型系統無法讓您表示類型參數的替換類型。 f1<number>
和typeof f1<number>
均無效。 TypeScript 對更高種類的類型沒有足夠的支持來表達這一點,至少不是純粹在類型級別。
在 TypeScript 3.4 中,TypeScript 引入了對從其他泛型函數推斷泛型函數的改進支持。 因此,雖然您不能僅在類型級別上進行您所詢問的類型操作,但您可以編寫一些函數讓編譯器無論如何都進行該操作。 例如:
function specify<A extends any[], R>(f: (...a: A) => R) {
return () => f;
}
specify()
function 接受任何 function,即使是通用的,並返回一個新的零參數 function,如果原始的也是通用的。 並且調用時 function 將返回原始 function。 這使您可以這樣做:
const f3 = specify(f1)<number>(); // const f3: (x: number) => number
specify(f1)
返回類型為<T>() => (x: T) => T
的 function 。 因此specify(f1)<number>()
產生非通用(x: number)=>number
function。 它也應該在運行時工作:
const sixNumberStillOkay = f3(n); // okay
const sixStringStillNotOkay = f3(s); // error! string is not number
我不確定您是否會經常將通用函數擴展到具體函數,以使specify()
值得; 這取決於你。
好的,希望有幫助; 祝你好運!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.