建立實例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')