App下載

什么是 TypeScript 泛型?

月亮醉酒到處跑 2023-09-30 10:21:10 瀏覽數(shù) (1145)
反饋

微信截圖_20230927103706

TypeScript 為什么要引入泛型?

泛型(Generics)是 Typescript 中很重要的一個(gè)特性,它可以幫助我們創(chuàng)建可重用的組件,同時(shí)還能具備類型安全性。

主要的優(yōu)點(diǎn)有:

  1. 更好的可重用性:通過(guò)泛型可以創(chuàng)建一個(gè)組件,使其可以支持多種類型,比如創(chuàng)建一個(gè)函數(shù)或類時(shí),不預(yù)先指定具體的類型,而是在使用的時(shí)候再指定類型。這樣就可以對(duì)不同的類型重復(fù)使用同一個(gè)組件。
  2. 類型安全:泛型會(huì)要求在使用組件時(shí)傳入的類型與組件內(nèi)部使用的類型一致,可以在編譯時(shí)發(fā)現(xiàn)錯(cuò)誤。
  3. 靈活性:可以只在需要的時(shí)候指定類型參數(shù),并且參數(shù)可以有多個(gè)。類型參數(shù)也可以限制約束條件來(lái)約束傳入的類型。
  4. 對(duì)于接口和類來(lái)說(shuō),泛型可以明確成員的類型,增強(qiáng)代碼的可讀性。

常見(jiàn)的泛型用法有:

  • 泛型函數(shù)和泛型類:可以定義泛型函數(shù)或泛型類,在實(shí)例化時(shí)指定類型參數(shù)
  • 泛型接口:可以定義泛型接口,使接口更靈活適用
  • 泛型約束:可以對(duì)泛型的類型參數(shù)加以約束

總之,泛型是 Typescript 強(qiáng)大的類型系統(tǒng)特性之一,可以構(gòu)建靈活、可重用且類型安全的組件,提高代碼質(zhì)量和可維護(hù)性。正確使用泛型能大大提升 Typescript 的開(kāi)發(fā)體驗(yàn)。

泛型是什么?

?泛型程序設(shè)計(jì)(generic programming)?是程序設(shè)計(jì)語(yǔ)言的一種風(fēng)格或范式

泛型允許我們?cè)趶?qiáng)類型程序設(shè)計(jì)語(yǔ)言中編寫代碼時(shí)使用一些以后才指定的類型,在實(shí)例化時(shí)作為參數(shù)指明這些類型 在typescript中,定義函數(shù),接口或者類的時(shí)候,不預(yù)先定義好具體的類型,而在使用的時(shí)候在指定類型的一種特性

假設(shè)我們用一個(gè)函數(shù),它可接受一個(gè) number 參數(shù)并返回一個(gè)number 參數(shù),如下寫法:

function returnItem (para: number): number { 
    return para 
} 

如果我們打算接受一個(gè) string 類型,然后再返回 string類型,則如下寫法:

function returnItem (para: string): string { 
    return para 
} 

上述兩種編寫方式,存在一個(gè)最明顯的問(wèn)題在于,代碼重復(fù)度比較高

雖然可以使用 any類型去替代,但這也并不是很好的方案,因?yàn)槲覀兊哪康氖墙邮帐裁搭愋偷膮?shù)返回什么類型的參數(shù),即在運(yùn)行時(shí)傳入?yún)?shù)我們才能確定類型

這種情況就可以使用泛型,如下所示:

function returnItem<T>(para: T): T { 
    return para 
}

可以看到,泛型給予開(kāi)發(fā)者創(chuàng)造靈活、可重用代碼的能力。

泛型的使用方式

泛型的使用方式主要有以下幾種:

1. 泛型函數(shù)

可以在函數(shù)名稱后添加尖括號(hào)來(lái)定義泛型函數(shù),在函數(shù)體中使用 T 來(lái)表示泛型類型。調(diào)用時(shí)指定類型參數(shù):

function identity<T>(arg: T): T {

  return arg; 

}

let output = identity<string>("myString");

2. 泛型接口

可以在接口名稱后添加尖括號(hào)來(lái)定義泛型接口,接口中的屬性則可以使用 T 來(lái)表示類型:

interface GenericIdentityFn<T> {

  (arg: T): T;

}

function identity<T>(arg: T): T {

  // ...

}

let myIdentity: GenericIdentityFn<number> = identity; 

3. 泛型類

可以在類名稱后添加尖括號(hào)來(lái)定義泛型類,類中的屬性或方法則可以使用 T 來(lái)表示類型:

class GenericNumber<T> {

  zeroValue: T;

  add: (x: T, y: T) => T;

}

let myGenericNumber = new GenericNumber<number>();

4. 泛型約束

可以通過(guò) extends 關(guān)鍵字添加約束條件:

interface Lengthwise {

  length: number;

}

function loggingIdentity<T extends Lengthwise>(arg: T): T {

  console.log(arg.length); 

  return arg;

}

這些是泛型的常見(jiàn)用法,可以靈活運(yùn)用泛型來(lái)實(shí)現(xiàn)組件的可重用性和類型安全。泛型的使用方式

泛型的應(yīng)用場(chǎng)景

泛型的常見(jiàn)應(yīng)用場(chǎng)景包括:

1. 封裝組件

可以使用泛型來(lái)封裝可重用的組件,比如創(chuàng)建一個(gè)通用的緩存組件:

class Cache<T> {

  private data: T;

  constructor(data: T) {

    this.data = data;

  }

  get() {

    return this.data;

  }

  set(data: T) {

    this.data = data;

  }

}

const numCache = new Cache<number>(123);

這樣這個(gè)緩存組件就可以支持不同的類型。

2. 函數(shù)重載

可以使用泛型給函數(shù)增加多種類型的重載定義:

function arrayOf<T>(value: T): T[];

function arrayOf<T>(value: T[]): T[];

function arrayOf<T>(value: T | T[]): T[] {

  return Array.isArray(value) ? value : [value];

}

3. 接口定義

可以使用泛型給接口增加靈活性:

interface Result<T> {

  data: T;

  error?: string;

}

const result: Result<number> = {

  data: 123

};

4. 類型別名

可以給類型別名增加泛型:

type PromiseResponse<T> = Promise<{

  data: T;

  error?: string; 

}>

5. 泛型約束

可以對(duì)泛型加以約束,限制泛型的類型范圍。

綜上,泛型的應(yīng)用場(chǎng)景非常廣泛,合理利用泛型可以大幅提高代碼的靈活性和復(fù)用性。


0 人點(diǎn)贊