摘要:往期第一課體驗第二課基礎類型和入門高級類型第三課泛型第四課解讀高級類型插一課本來打算接著上節課把高級類型都講完但是寫著寫著我發現高級類型中有很多地方都需要泛型的知識那么先插一節泛型什么是類型變量和泛型變量的概念我們都知道可以表示任意數據類型
往期
第一課, 體驗typescript
第二課, 基礎類型和入門高級類型
第三課, 泛型
第四課, 解讀高級類型
插一課本來打算接著上節課, 把高級類型都講完, 但是寫著寫著我發現高級類型中, 有很多地方都需要泛型的知識, 那么先插一節泛型.
什么是"類型變量"和"泛型"變量的概念我們都知道, 可以表示任意數據, 類型變量也一樣, 可以表示任意類型:
// 在函數名后面用"<>"聲明一個類型變量 function convert(input:T):T{ return input; }
convert中參數我們標記為類型T, 返回值也標記為T, 從而表示了: 函數的輸入和輸出的類型一致. 這樣使用了"類型變量"的函數叫做泛型函數, 那有"泛型類"嗎?
注意: T是我隨便定義的, 就和變量一樣, 名字你可以隨便起, 只是建議都是大寫字母,比如U / RESULT.
class Person {
who: U;
constructor(who: U) {
this.who = who;
}
say(code:U): string {
return this.who + " :i am " + code;
}
}
在類名后面通過"<>"聲明一個類型變量U, 類的方法和屬性都可以用這個U, 接下來我們使用下泛型類:
let a = new Person("詹姆斯邦德"); a.say(007) // 錯誤, 會提示參數應該是個string a.say("007") // 正確
我們傳入了類型變量(string),告訴ts這個類的U是string類型, 通過Person的定義, 我們知道say方法的參數也是string類型, 所以a.say(007)會報錯, 因為007是number. 多以我們可以通過傳入類型變量來約束泛型.
其實我們也可以不指定類型變量為string, 因為ts可以根據實例化時傳入的參數的類型推斷出U為string類型:
let a = new Person("詹姆斯邦德");
// 等價 let a = new Person("詹姆斯邦德");
a.say(007) // 錯誤, 會提示參數應該是個string
a.say("007") // 正確
其實方法和函數的定義方式一樣:
class ABC{
// 輸入T[], 返回T
getFirst(data:T[]):T{
return data[0];
}
}
說實話ts的文檔我找了好幾遍, 也沒看到他給泛型正式做定義, 只是表達他是一種描述多種類型(類型范圍)的格式, 我覺得有點抽象, 我用自己的理解具象下: 用動態的類型(類型變量)描述函數和類的方式.
泛型類型我們可以用類型變量去描述一個類型(類型范圍), ts的數組類型Array本身就是一個泛型類型, 他需要傳遞具體的類型才能變的精準:
let arr : Array; arr = ["123"]; // 錯誤, 提示數組中只可以有number類型 arr = [123];
下面我們自己定義一個泛型類型, 就對開頭的convert函數定義:
function convert泛型接口(input:T):T{ return input; } // 定義泛型類型 interface Convert { (input:T):T } // 驗證下 let convert2:Convert = convert // 正確不報錯
通過傳入不同的類型參數, 讓屬性更靈活:
interface Goods擴展類型變量(泛型約束){ id:number; title: string; size: T; } let apple:Goods = {id:1,title: "蘋果", size: "large"}; let shoes:Goods = {id:1,title: "蘋果", size: 43};
function echo(input: T): T { console.log(input.name); // 報錯, T上不確定是否由name屬性 return input; }
前面說過T可以代表任意類型, 但對應的都是基礎類型, 所以當我們操作input.name的時候就需要標記input上有name屬性, 這樣就相當于我們縮小了類型變量的范圍, 對泛型進行了約束:
// 現在T是個有name屬性的類型 function echo一個泛型的應用, 工廠函數(input: T extends {name:string}): T { console.log(input.name); // 正確 return input; }
function create(O: {new(): T|U; }): T|U { return new O(); }
主要想說3個知識點:
可以定義多個類型變量.
類型變量和普通類型用法一直, 也支持聯合類型/交叉類型等類型.
如果一個數據是可以實例化的, 我們可以用{new(): any}表示.
不要亂用泛型泛型主要是為了約束, 或者說縮小類型范圍, 如果不能約束功能, 就代表不需要用泛型:
function convert(input:T[]):number{ return input.length; }
這樣用泛型就沒有什么意義了, 和any類型沒有什么區別.
總結泛型是編譯型語言最重要的特性, 泛型寫的好就會讓人覺得代碼很高級, 可以說泛型是一個成手ts程序員必須熟練的技巧, 面試的時候是加分項, 所以大家寫代碼多多用泛型練習哦, 加油ヾ(?°?°?)??,下面是的用ts寫的幾個小項目,寫的不好, 就是有份熱情, 拋磚引玉, 大家肯定能寫出更好的:
手勢庫: https://github.com/any86/any-...
命令式調用vue組件: https://github.com/any86/vue-...
工作中常用的一些代碼片段: https://github.com/any86/usef...
一個mini的事件管理器: https://github.com/any86/any-...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.hztianpu.com/yun/105671.html
摘要:更新啦第一課體驗第二課基礎類型和入門高級類型第三課泛型第四課解讀高級類型要來了看了的視頻特別興奮要來了是用開發的我揣測在的帶領下會成為主流呢要不先學點年最酷的前端技術我是年初開始使用的自從開始用上了就喜歡上了真的愛不釋手最愛他幾點很多小錯誤 更新啦 第一課, 體驗typescript 第二課, 基礎類型和入門高級類型 第三課, 泛型 第四課, 解讀高級類型 vue3要來了 看了vue ...
摘要:導航第一課體驗第二課基礎類型和入門高級類型第三課泛型第四課解讀高級類型很重要這一節很重要可以說是的最核心部分這一節學完其實就可以開始用寫代碼了想想中的再看看標題中的類型字所以請大家務必認真什么是入門高級類型因為高級類型的內容比較多但是有些基 導航 第一課, 體驗typescript 第二課, 基礎類型和入門高級類型 第三課, 泛型 第四課, 解讀高級類型 很重要 這一節很重要, 可以說...
摘要:往期目錄第一課體驗第二課基礎類型和入門高級類型第三課什么是泛型第四課解讀高級類型第五課什么是命名空間什么時候要用命名空間如果你發現自己寫的功能函數類接口等越來越多你想對他們進行分組管理就可以用命名空間下面先用類舉例仔細看你會發現下還有在這里 往期目錄 第一課, 體驗typescript 第二課, 基礎類型和入門高級類型 第三課, 什么是泛型? 第四課, 解讀高級類型 第五課, 什么是命...
摘要:直達第一課體驗第二課基礎類型和入門高級類型第三課泛型第四課解讀高級類型第五課什么是命名空間回顧第二課的時候為了更好的講解基礎類型所以我們講解了一部分高級類型比如接口聯合類型交叉類型本節課我會把剩余高級類型都講完知識點摘要本節課主要關鍵詞為自 直達 第一課, 體驗typescript 第二課, 基礎類型和入門高級類型 第三課, 泛型 第四課, 解讀高級類型 第五課, 什么是命名空間(na...
閱讀 1088·2023-04-25 19:40
閱讀 3791·2023-04-25 17:41
閱讀 3149·2021-11-11 11:01
閱讀 2885·2019-08-30 15:55
閱讀 3399·2019-08-30 15:44
閱讀 1564·2019-08-29 14:07
閱讀 642·2019-08-29 11:23
閱讀 1505·2019-08-27 10:54