<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
使用 TypeScript 進行開發也已經有段日子了,雖然最開始接觸後以為這不就和 Java 一樣一樣的麼,然而越深入瞭解越發現還真不一樣~不過有些概念來說是相通的,比如泛型。 Java 裡也有函數過載,但是和 TS 差別還是挺大的,那就通過一個排序功能來了解一下 TS 中的泛型過載吧
ts-node 是 typescript 的 node.js 解釋和執行器,也就是說,它可以像 node 執行 JavaScript 一樣執行 typescript 程式碼。
使用方式也很簡單,在專案中安裝 typescript 和 ts-node 的依賴後使用 ts-node 命令執行 ts 檔案即可。
1.在命令列安裝依賴
npm install typescript ts-node
2.使用 ts-node 執行 ts 檔案(這裡使用 npx 來執行 ts-node,因為 ts-node 是在本地專案中安裝的,如果直接使用的話會報命令找不到的錯誤,當然如果在全域性安裝了 ts-node npm 包就直接可以使用 ts-node 來執行,如果只是本地安裝了,那麼需要加上 npx,這是會到 node_modules 資料夾中找到 ts-node 包來進行執行。)
全域性安裝了: ts-node: ts-node xxx.ts
本地專案安裝了 ts-node: npx ts-node xxx.ts
補充: ts-node 也可以直接在命令列中編寫和執行 ts 程式碼,像 python 那樣,
如下圖:
tsc 顧名思義就是 typescript 的編譯器名稱,在安裝完 typescript 後,即可以使用 tsc 命令執行 ts 檔案,當然不同於 ts-node 能夠直接執行 ts 檔案,tsc 只是將 ts 檔案編譯後輸出成 js 檔案,然後可以再通過 node 來執行生成的 js 檔案。
tsc 有許多的設定項,當執行 tsc --init 時可以在專案中生成 tsconfig.json 檔案,這個檔案裡面包含了許多的設定,包括設定編譯後的檔案輸出路徑,編譯後的檔案用哪種模組規範以及相容 es6 語法等等選項。
//1.安裝 typescript npm install typescript //2.使用 tsc 生成 tsconfig.json 檔案 npx tsc --init //3.使用 tsc 編譯 ts 檔案 npx tsc xxx.ts
TS 中的函數過載並不像其它語言中的函數過載一樣,和其它語言如 Java 比起來,更像是一種偽過載,它不能像 Java 中過載那樣實現同樣的函數名,但是引數個數不一樣,而是更多的為型別推斷服務。
首先,使用 TS 來實現一個快速排序函數:
function quickSort<T>(arr: Array<T>): T[] { if (arr.length < 2) return arr const left: Array<T> = [] const right: Array<T> = [] const mid = arr.splice(Math.floor(arr.length / 2), 1)[0] for (let item of arr) { if (item < mid) { left.push(item) } else { right.push(item) } } return quickSort(left).concat(mid, quickSort(right)) }
上面這段程式碼是使用泛型實現的快速排序函數,快速排序比氣泡排序的效能要好很多,基本思想就是分治(divide and conquer),簡單來說就是先選一個元素作為中間數,然後分成兩部分,小於這個元素的部分,和大於這個元素部分,接著再使用遞迴分別進行處理這兩部分,將排序任務分解到最小,然後再合併。
上面程式碼中的快速排序方式,如果傳遞的是英文陣列那就沒問題,但是如果傳遞的是中文陣列,那就不能正常排序了,所以中文陣列需要單獨進行處理,使用下面的函數:
// 通過正規表示式,判斷是否是中文陣列 function isChinese<T>(arr: Array<T>): boolean { const pattern = /[u4e00-u9fa5]+/g; return arr.some((item: any) => { return pattern.test(item) }) } // 中文排序 function chineseSort<T>(arr: Array<T>): T[] { return arr.sort((first, second) => { return (first as any).localeCompare(second, 'zh-CN') }) }
如果是中文陣列,那麼使用陣列內建的 sort 函數進行排序。
接下來,如果需要將英文陣列中的每一項進行排序,則還需要單獨的函數進行處理:
// 英文自排序 function strSelfSort(str: string): string { const strArr = str.split('') return quickSort(strArr).join('') }
實現英文字串自排序就是先將字串進行 split 分割成字元陣列,然後傳遞到之前寫的快速排序函數中,得到結果後再通過 join 函數拼接成字串返回。
那麼,接下來將上面的幾種排序功能整合成一個單獨的通用函數:
// 通用的排序函數 function sort<T>(data: T): T[] | string { if (typeof data === "string") { return strSelfSort(data) } if (data instanceof Array) { if (isChinese(data)) { return chineseSort(data) } const newArr = data.map((item) => { return typeof item === "string" ? strSelfSort(item) : item }) return quickSort(newArr) } throw new Error(`data must be string or array. ${data}`) }
通過上面的通用排序函數可以看出,在函數內部通過排序傳遞的資料型別,如果是 string 則呼叫自排序,接著如果是陣列的話,再判斷是否是中文陣列,如果是,則呼叫中文陣列排序函數進行排序,不是的話就認定為是英文陣列,英文陣列首先使用 map 函數遍歷,判斷陣列中如果存在 string 型別就先呼叫字串自排序函數進行排序,否則就原樣返回,最後再通過快速排序函數進行排序,這樣就完成了英文陣列既每一項都排序了,整體陣列也進行了排序。
雖然上面的排序函數功能已經比較完善了,但是有一點不太好的地方就是這個函數返回了一個聯合型別 T[] | string,這樣就會導致通過這個函數排序的結果不能確切的推斷出具體的型別,而只能是個聯合型別,那麼我們也只能使用這個聯合型別裡共有的方法提示,
如下圖:
這裡簡單的呼叫了一下寫好的排序函數,返回的結果型別竟然是:string | string[][] 的聯合型別,這樣的返回結果對於開發後續功能來說很不友好,那麼接下來,就使用 TS 中的函數過載來完善一下上面的排序函數:
// 使用函數過載重構排序函數 function sort(data: string): string function sort<T>(data: T): T function sort(data: any): any { if (typeof data === "string") { return strSelfSort(data) } if (data instanceof Array) { if (isChinese(data)) { return chineseSort(data) } const newArr = data.map((item) => { return typeof item === "string" ? strSelfSort(item) : item }) return quickSort(newArr) } throw new Error(`data must be string or array. ${data}`) }
關於 TS 的函數過載,就是隻有一個實現的函數,其餘都是函數簽名,而且必須放在實現函數的上面,在呼叫這個函數的時候,只會顯示上面的函數簽名函數,而不會展示具體實現的函數,但是實際執行的卻是那個實現函數,在這種情況下,通過使用函數過載寫個兩個不同引數和返回值的函數簽名提供給呼叫者使用,而在具體實現函數中去相容處理,這樣做的好處就是呼叫者得到的返回值型別可以是某個具體的型別了,而不再是個聯合型別,更有益於後面的開發。
通過使用 TS 的函數過載解決了當一個函數返回一個聯合型別時,型別推斷不確定的問題,在某些會返回聯合型別的場景下可以嘗試使用,方便後續的型別推斷操作,所以說,TS 的一切真的都是為型別而服務的,怎麼寫好 TS 程式碼其實就是在更好的完善型別推斷,型別系統的過程,只有更好更準確的型別推斷,才能發揮 TS 的作用,讓編譯器在開發過程中智慧的告訴開發者有哪些屬性和方法可以呼叫,並且在呼叫了錯誤的屬性和方法後可以及時提醒開發者。
到此這篇關於TypeScript 泛型過載函數的使用方式的文章就介紹到這了,更多相關TypeScript 泛型過載函數 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45