TS: 泛型


學 Java 的時候總會提到泛型,現在 TS 也有了,他們的用法都差不太多。泛型可以理解為廣泛的類型。

為什么要用泛型

先來了解下泛型有什么用。先看下面定義的一個函數:

function itself(a: number): number {
    return a
}

itself(1) // 1

 

上面的函數就是簡單的傳入一個數,返回一個數,但是現在想傳入字符串,返回字符串呢?或者再加傳入數組,返回數組呢?這就需要用到泛型了。

function itself<T>(a: T):T {
    return a
}

console.log(itself(true)) // true
console.log(itself(1))   // 1
console.log(itself('1')) // '1'
console.log(itself([1, 2, 3])) // [1, 2, 3]

 

從上面的例子可以看到,T 有點像是一個臨時變量一樣,先推斷出傳入參數的類型,將這個類型賦值到 T T = XXX 類型,后面就直接 返回的類型 = T = XXX 類型。這么說可能不那么准確,但是可以看到 T 就是一個占位符。

如果調用函數時使用顯式聲明可能會更直觀。

function itself<T>(a: T):T {
    return a
}

console.log(itself<boolean>(true)) // true
console.log(itself<number>(1))   // 1
console.log(itself<string>('1')) // '1'
console.log(itself<Array<number>>([1, 2, 3])) // [1, 2, 3

 

這里發現 Array<number> 里也是用了泛型的,這樣可以聲明數組里元素的類型。

接口與泛型

上面都是傳基本類型(除了 Array),下面看看接口與泛型的配合。

interface Human {
    name: string
    age: number
}
interface Animal {
    category: string
}

function create<T>(what: T): T {
    return what
}

create<Human>({
    name: 'Jack',
    age: 18
})

create<Animal>({
    category: 'dog'
})

 

用法幾乎一樣,Easy~。

有了接口這個東西后,我們可以玩更高級一點的。現在我想造一個 Human,規定這個 Human 一定要有 JJ,可以這么寫。

interface JJ {
    jjSize: string
    jjLength: number
}
interface Human {
    name: string
    age: number
}

function create<T extends JJ>(what: T): T {
    return what
}

create({
    name: 'Jack',
    age: 18,
    jjSize: 'large',
    jjLength: 18
})

create({
    name: 'Jack',
    age: 18
}) // 報錯:沒有 jjSize 和 jjLength

 

上面的這個用法叫做泛型的約束,像剛剛說的這個 Human 一定要有 JJ,這就是一個約束。

類與泛型

說完接口,肯定逃不了要說類了。我們先來看一段 JS 的代碼。

function create(C) {
    return new C()
}

 

正確的理解應該是傳入一個構造函數 C,然后返回 C 的實例,沒了。但是這個函數啥約束都沒有,如果傳入一個字符串 "Hello" 呢?那不是炸了?所以我們要用 TS 里的泛型去約束它。

function create<T>(C: { new () }) {
    return new C()
}

 

兩個括號里寫的是 new () 說明傳入的 C 是可以用 new C() 的。然后我們再加個上返回類型和傳入的類型,可以寫成這樣。

function create<T>(c: { new (): T }): T {
    return new c()
}

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM