小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

TypeScript 的 generic 函數(shù)

 汪子熙 2021-06-29

官方鏈接

編寫一個函數(shù),其中輸入的類型與輸出的類型相關(guān),或者兩個輸入的類型以某種方式相關(guān)。 讓我們考慮一個返回數(shù)組第一個元素的函數(shù):

function firstElement(arr: any[]) {
  return arr[0];
}

這個函數(shù)完成了它的工作,但不幸的是返回類型為 any。 如果函數(shù)返回數(shù)組元素的類型會更好。

在 TypeScript 中,當我們想要描述兩個值之間的對應(yīng)關(guān)系時,會使用泛型。 我們通過在函數(shù)簽名中聲明一個類型參數(shù)來做到這一點:

function firstElement<T>(arr: T[]): T {
  return arr[0];
}

const arr: string[] = ['1', '2', '3'];

const result = firstElement(arr);

console.log(result);

const result1:number = firstElement(arr);

TypeScript 的類型推斷 - Type inference

function map<Input, Output>(arr: Input[], func: (arg: Input) => Output): Output[] {
  return arr.map(func);
}

注意,上面代碼的 Inout,Output 可以被 T, V 替代,但是可讀性不如前者。

Type constrains - 類型約束

我們已經(jīng)編寫了一些可以處理任何類型值的通用函數(shù)。 有時我們想關(guān)聯(lián)兩個值,但只能對某個值的子集進行操作。 在這種情況下,我們可以使用約束來限制類型參數(shù)可以接受的類型種類。

讓我們編寫一個函數(shù),返回兩個值中較長的一個。 為此,我們需要一個長度屬性,它是一個數(shù)字。 我們通過編寫 extends 子句將類型參數(shù)限制為該類型:

function longest<Type extends { length: number }>(a: Type, b: Type) {
  if (a.length >= b.length) {
    return a;
  } else {
    return b;
  }
}

// longerArray is of type 'number[]'
const longerArray = longest([1, 2], [1, 2, 3]);
console.log(longerArray);

// longerString is of type 'string'
const longerString = longest("alice", "bob");
console.log(longerString);

// Error! Numbers don't have a 'length' property
const notOK = longest(10, 100);

最后一個函數(shù)調(diào)用會出現(xiàn)編譯錯誤,因為 TypeScript 基本類型 number 并不存在名稱為 length 的屬性。

同 Java 相比,TypeScript 的類型約束的強大之處在于,extends 后面緊跟的不需要是 TypeScript 的 built-in type,比如本例里的:

{
length: number
}

意思是,只要該函數(shù)傳入的類型,至少包含類型為 number 的 length 屬性即可。

Specifying Type Arguments

TypeScript 通??梢栽诜盒驼{(diào)用中推斷出預(yù)期的類型參數(shù),但并非總是如此。 例如,假設(shè)您編寫了一個函數(shù)來組合兩個數(shù)組:

function combine<Type>(arr1: Type[], arr2: Type[]): Type[] {
  return arr1.concat(arr2);
}

編譯錯誤:

解決辦法:使用尖括號語法,顯式傳入類型參數(shù):這里 T = string | number,意思是接收 string 或者 number 類型均可。

編寫 generic 函數(shù)的最佳實踐

編寫泛型函數(shù)很有趣,而且很容易被類型參數(shù)沖昏頭腦。 有太多類型參數(shù)或在不需要它們的地方使用約束會使推理不那么成功,使函數(shù)的調(diào)用者感到沮喪。

最佳實踐1 - Push Type Parameters Down

function firstElement1<Type>(arr: Type[]) {
  return arr[0];
}

function firstElement2<Type extends any[]>(arr: Type) {
  return arr[0];
}

// a: number (good)
const a = firstElement1([1, 2, 3]);
// b: any (bad)
const b = firstElement2([1, 2, 3]);

乍一看,兩種方法似乎相同,但 firstElement1 是編寫此函數(shù)的更好方法。 它的推斷返回類型是 Type,但 firstElement2 的推斷返回類型是 any,因為 TypeScript 必須使用約束類型解析 arr[0] 表達式,而不是在調(diào)用期間“等待”解析元素。

最佳實踐 2- Use Fewer Type Parameters

function filter1<Type>(arr: Type[], func: (arg: Type) => boolean): Type[] {
  return arr.filter(func);
}

function filter2<Type, Func extends (arg: Type) => boolean>(
  arr: Type[],
  func: Func
): Type[] {
  return arr.filter(func);
}

我們創(chuàng)建了一個不關(guān)聯(lián)兩個值的類型參數(shù) Func。 這總是一個危險信號,因為這意味著想要指定類型參數(shù)的調(diào)用者必須無緣無故地手動指定一個額外的類型參數(shù)。 Func 不會做任何事情,只會讓函數(shù)更難閱讀和推理!

最佳實踐3 - Type Parameters Should Appear Twice

function greet<Str extends string>(s: Str) {
  console.log("Hello, " + s);
}

greet("world");

這個例子里, Str 只出現(xiàn)了一次,因此根本毫無必要。

可以簡寫成:

function greet(s: string) {
  console.log("Hello, " + s);
}

請記住,類型參數(shù)用于關(guān)聯(lián)多個值的類型。 如果一個類型參數(shù)在函數(shù)簽名中只使用一次,它就沒有任何關(guān)系。

    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多