日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

TypeScript中的泛型(泛型函數、接口、類、泛型約束)

作者:jieyucx 更新時間: 2023-07-26 編程語言

一、泛型函數

TypeScript泛型是一種可以使代碼具有更高的可重用性和泛化能力的特性。通過泛型,我們可以定義一種通用的類型或函數,使其能夠應對多種類型的輸入。泛型在類、函數、接口等多種場景下都可以使用。

具體來說,在定義泛型函數時,我們可以使用來表示一個類型變量,這樣我們就可以在函數中使用這個泛型類型來作為參數類型、返回值類型或變量類型等。例如:

function echo<T>(arg: T): T {
    return arg;
}

let myIdentity: <T>(arg: T) => T = echo;

在這個例子中,我們定義了一個echo函數,它使用泛型類型變量T作為輸入參數類型和返回值類型,這樣我們就可以使用不同類型的參數來調用該函數,例如:

console.log(echo('Hello TypeScript!')); // 輸出:Hello TypeScript!
console.log(echo(123)); // 輸出:123

二、泛型類

在類的定義中使用泛型,也可以大大提高代碼的復用性和靈活性。例如下面的代碼:

class Stack<T> {
    private items: T[] = [];

    push(item: T) {
        this.items.push(item);
    }

    pop(): T {
        return this.items.pop();
    }
}

let strStack = new Stack<string>();
strStack.push('apple');
strStack.push('banana');
strStack.push('cherry');

console.log(strStack.pop());
console.log(strStack.pop());
console.log(strStack.pop());

在上面的代碼中,定義了一個Stack類,并聲明了泛型類型T,用于在push和pop方法中進行類型的轉換。通過傳入不同類型的參數,可以得到不同類型的Stack實例。

三、泛型接口

interface Map<K, V> {
    set(key: K, val: V): void;
    get(key: K): V | undefined;
    has(key: K): boolean;
    clear(): void;
}

let numMap: Map<number, string> = {
    set(key: number, val: string) {
        // 添加鍵值對
    },
    get(key: number): string | undefined {
        // 獲取鍵值對
    },
    has(key: number): boolean {
        // 判斷是否存在
    },
    clear() {
        // 清空Map
    }
};

numMap.set(1, 'apple');
numMap.set(2, 'banana');

console.log(numMap.get(1));
console.log(numMap.get(2));

在上面的代碼中,定義了一個Map接口,并使用泛型K和V來約束鍵和值的類型。通過傳入不同類型的參數,可以得到不同類型的Map實例,并實現對不同類型鍵值對的操作。

四、泛型約束、泛型限制用法<T> extends {屬性:類型}

在 TypeScript 中,泛型約束是一種讓泛型類型參數只能取某些特定類型的值的機制。這個特定類型的限制可以是一個接口、類、枚舉或其他類型。

例如,假設我們有一個泛型函數,它接受一個類型參數 T 和一個對象參數 obj,這個函數返回 obj 中的第一個 T 類型的屬性值:

function getPropertyValue<T>(obj: object): T {
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      let value = obj[key];
      if (value instanceof T) {
        return value;
      }
    }
  }
  throw new Error(`No property of type ${T.name} found.`);
}

但是,這個函數可能會遇到一些問題。例如,如果我們調用 getPropertyValue({ a: ‘1’, b: 2, c: 3 }),那么會拋出一個錯誤,因為字符串 ‘1’ 不是一個 number 類型。

為了解決這個問題,我們可以使用泛型約束來限制 T 只能取某些特定類型的值。例如,我們可以要求 T 必須是實現了 Number 接口的類型:

interface Number {
  new (value?: any): number;
  (value?: any): number;
  readonly NaN: number;
  readonly MAX_VALUE: number;
  readonly MIN_VALUE: number;
  readonly NEGATIVE_INFINITY: number;
  readonly POSITIVE_INFINITY: number;
}

function getPropertyValue<T extends Number>(obj: object): T {
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      let value = obj[key];
      if (value instanceof T) {
        return value;
      }
    }
  }
  throw new Error(`No property of type ${T.name} found.`);
}

現在,如果我們調用 getPropertyValue({ a: ‘1’, b: 2, c: 3 }),就會得到一個類型錯誤,因為 ‘1’ 不是一個實現了 Number 接口的類型。但是,如果我們調用 getPropertyValue({ a: 1, b: 2, c: 3 }),就能得到正確的結果了。

另一泛型約束\<key extends keyof Type>

在 TypeScript 中,<key extends keyof Type> 是一種泛型約束方式,用于限制一個泛型類型參數 key 的范圍。

其中,keyof 關鍵字可以用于獲取一個類型 Type 的所有屬性名,返回一個字符串字面量類型,例如:

interface Person {
  name: string;
  age: number;
}

type PersonKeys = keyof Person; // "name" | "age"

<key extends keyof Type> 中,extends 關鍵字表示限制 key 的取值只能是 Type 類型中已有的屬性名。也就是說,只有 key 取值為 Type 類型中已有的屬性名才符合類型約束,例如:

function getValueByKey<T extends object, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

const person = {
  name: 'Bob',
  age: 25,
};
const name = getValueByKey(person, 'name'); // name 的類型是 string
const age = getValueByKey(person, 'age'); // age 的類型是 number
const gender = getValueByKey(person, 'gender'); // 編譯報錯,gender 不是 person 中的屬性

在上面的例子中,getValueByKey 函數接收兩個參數:一個泛型類型參數 T,代表輸入對象的類型;一個泛型類型參數 K,代表屬性名的類型。

extends keyof T 約束了類型參數 K 必須是輸入對象類型 T 中已存在的屬性名。因此,調用 getValueByKey 函數傳入一個不存在的屬性名 gender 會引發編譯錯誤。

五、使用泛型注意點

在編寫泛型方法時,應該注意以下幾點:

  1. 泛型形參的名稱應該描述清楚其作用和范圍,盡量不要使用單個字母的形參名稱;
  2. 在使用泛型類型的屬性或方法時,應該確保該屬性或方法在所有可能的泛型類型中都是存在的,不要使用不存在的屬性或方法;
  3. 在使用泛型類型的操作符時,應該考慮不同類型之間可能的差異性和兼容性問題,避免出現類型錯誤

原文鏈接:https://blog.csdn.net/jieyucx/article/details/131346916

  • 上一篇:沒有了
  • 下一篇:沒有了
欄目分類
最近更新