TypeScript徹底解讀(26課時)_6.TypeScript徹底解讀-泛型

6.TypeScript徹底解讀-泛型

建立實例ts文件generics.ts數組

 

在index.ts內引入編輯器

 

fill是填充數組,建立的數組的元素數是times,填充的值就是接收的value的值函數

 這裏傳入一個2的數量,這樣返回的就是5個2的數組spa

 

返回每一個都+1的結果3d

 返回每一個元素的length這樣就是有錯誤的,由於咱們的數值類型是沒有length這個屬性的code

傳入字符串,是有length屬性的對象

雖然是能夠,可是丟失了類型的檢測。這裏咱們就須要用到泛型blog

使用泛型約束函數的類型索引

泛型變量T,調用函數的時候會手動傳入這個類型,T就表明固定的一種類型,這樣傳入的value的值類型也是T,最終函數返回的類型也是T類型的數組接口

調用的時候傳入類型T爲number類型。number類型是不存在屬性length的

咱們調用他的toFixed方法是能夠的。這個就是泛型的簡單使用

const getArray = <T>(value: T, times: number = 5): T[] =>{
    return new Array(times).fill(value)
}

console.log(getArray<number>(123, 3).map((item) => item.toFixed()))

 

 

詳細講下泛型變量,T就是泛型變量,可是T不是固定寫法,能夠換成u換成k都是能夠的,通常習慣性用一個大寫的字母,通常T用的比較多,這樣就能保證咱們指定返回類型

複雜一點的例子,用了兩個泛型變量

 

循環輸出元素的第一個值和第二個值

 

第一個元素是數值類型,調用length就會報錯,第二個元素是字符串類型,調用toFixed也會報錯

在調用getArray的方法的時候,並無明確的傳入類型,若是咱們不傳的話,ts編輯器也會根據咱們傳入的值推斷出類型

固然也能夠明確的制定參數的類型

 

const getArray = <T, U>(param1: T, param2: U, times: number): Array<[T, U]> => {
    return new Array(times).fill([param1, param2])
}
//console.log(getArray(1, 'a', 3))
getArray<number, string>(1, 'a', 3).forEach((item) =>{
    console.log(item[0])
    console.log(item[1])
})

 

 

泛型在類型定義中的使用

可使用泛型定義泛型函數類型

這樣調用就會報錯

接下來使用類型別名定義泛型函數類型

type GetArray = <T>(arg: T, times: number) => T[]
let getArray: GetArray = (arg: any, times: number) => {
    return new Array(times).fill(arg)
}

 

接口的形式定義泛型函數類型

interface GetArray {
    (arg: any, times: number): any[]
}

 

使用泛型的形式

個人電腦上沒有自動變成類型別名的形式

interface GetArray {
    <T>(arg: T, times: number): T[]
}

 

泛型變量還能夠提到接口的最外層

interface GetArray<T> {
    (arg: T, times: number): T[]
}

 

除了定義函數,還能夠添加屬性,只要把泛型變量放到最外層,裏面全部地方均可以使用這個泛型變量

泛型約束

泛型約束對泛型變量的條件限制

 

如今想對T有個要求,不能隨便傳任何值,只能傳帶length屬性的(數組、字符串、自定義的對象裏面寫個length屬性)

這裏傳遞的是一個數組是能夠的

傳入數字目前是能夠的,咱們要實現傳入數字讓不能夠。由於數字是沒有length的屬性的

咱們這個泛型變量加限制

interface ValueWithLength {
    length: number
}
const getArray = <T extends ValueWithLength>(arg: T, times) =>{
    return new Array(times).fill(arg)
}
getArray([1, 2], 3)
getArray(123, 3)

 傳入字符串就不報錯, 由於字符串有length的了屬性

傳入一個對象手打一個length屬性也是能夠的

interface ValueWithLength {
    length: number
}
const getArray = <T extends ValueWithLength>(arg: T, times) =>{
    return new Array(times).fill(arg)
}
getArray([1, 2], 3)
getArray({
    length: 3
}, 3)

 這裏就是使用extends來限制泛型變量,這就是泛型約束

在泛型約束中使用類型參數

定義一個對象,只能訪問對象上存在的屬性時就用到了

定義一個函數,傳入對象和屬性名稱,返回對象上的這個屬性名稱

 

對這個函數提供類型的提示,讓使用這個函數的人在編譯階段就意識到這個錯誤。這個時候就是用泛型變量

keyof是個索引類型,在後面高級類型的時候會講到,

keyof T:能夠理解爲 返回T這個對象上全部的屬性名構成的數組

const getProp = <T, K extends keyof T>(object: T, propName: K) => {
    return object[propName]
}
const objs = {
    a: 'a',
    b: 'b',
}
getProp(objs, 'a')
getProp(objs, 'c')
相關文章
相關標籤/搜索