簡體   English   中英

如何在 Typescript 中定義泛型函數類型; 兩種相似的方式?

[英]How to define a generic function type in Typescript; two similar ways?

我正在嘗試在 Typescript 中定義一些通用函數類型。 似乎有兩種類似的方法可以做到這一點,而且它們都有效。 然而,第二種形式——見下文ConcatY似乎不那么靈活,或者至少我不知道如何表明一個函數采用其中一種具有特定參數類型。 有沒有辦法定義一個采用ConcatY表示數字的函數? 一般來說,我應該如何考慮這兩種定義泛型函數的方式之間的差異?

// Two similar looking function types
type ConcatX<T> = (a: T, b: T) => T;
type ConcatY = <T>(a: T, b: T) => T;

// Can create instances of each of these types
const sum: ConcatX<number> = (a, b) => a + b;
const product: ConcatY = (a: number, b: number) => a + b;

// Can define a function that takes a ConcatX
function DoMathX(sum: ConcatX<number>) {
  console.log(`1 + 1 is ${sum(1, 1)}`);
}

// But can't define a function that takes a ConcatY for numbers
// A and B are "unknown"
// Or is there a way?
function DoMathTwo(sum: ConcatY) {}

這:

type ConcatX<T> = (a: T, b: T) => T;

是泛型類型別名,其中包含使用泛型參數的函數。 一旦類型被解析,這個函數使用的泛型參數就會被鎖定。 當某些類型需要設置函數的類型時,這會很方便。

例如這里:

const sum: ConcatX<number> = (a, b) => a + b;

這表示,在此函數的外部,您聲明此函數的參數是數字。

請注意,這根本不是函數類型的一部分。 這種方法與以下方法沒有根本區別:

type ContatX<T> = { sum(a: T, b: T): T, someValue: T }

關鍵是T完全設置在函數之外,函數只是選擇使用它。


這:

type ConcatY = <T>(a: T, b: T) => T;

是一個泛型函數 泛型參數在調用函數時設置,每次調用時都可以不同。 並且可以從參數ab的類型推斷該參數。

您不能在這里提前鎖定T ,因為T是在調用函數時決定的,而不是更早

這意味着沒有只接受數字的ConcatY子類型。 要在此處輸入防止不良使用,您可以檢查返回類型:

const resultStr: string = sum(1,2) // error: cannot assign number to string
const resultNum: num = sum('a','b') // error: cannot assign string to number

在這兩種情況下,函數調用都是完全有效的,但結果不是類型系統所期望的,因此您會收到錯誤消息。


如果您想要參數必須是數字的特定 concat 子類型,那么您需要通用類型ConcatX

但是,如果您的函數可以接受許多不同的參數,並且返回類型取決於這些參數的類型,並且您不知道提前調用它的確切類型,那么您需要通用函數ContactY

這一切都意味着,如果您想:

“指示一個函數采用其中一個具有特定參數類型”

然后您需要使用帶有泛型參數的ContactX來創建一個函數類型,其中T鎖定為您想要的任何內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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