欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

TypeScript?泛型重載函數(shù)的使用方式

 更新時間:2022年08月02日 11:43:45   作者:彼得潘ing  
這篇文章主要介紹了TypeScript?泛型重載函數(shù)的使用方式,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下

前言

使用 TypeScript 進(jìn)行開發(fā)也已經(jīng)有段日子了,雖然最開始接觸后以為這不就和 Java 一樣一樣的么,然而越深入了解越發(fā)現(xiàn)還真不一樣~不過有些概念來說是相通的,比如泛型。 Java 里也有函數(shù)重載,但是和 TS 差別還是挺大的,那就通過一個排序功能來了解一下 TS 中的泛型重載吧

TypeScript 的運(yùn)行環(huán)境

1. ts-node

ts-node 是 typescript 的 node.js 解釋和執(zhí)行器,也就是說,它可以像 node 執(zhí)行 JavaScript 一樣執(zhí)行 typescript 代碼。

使用方式也很簡單,在項(xiàng)目中安裝 typescript 和 ts-node 的依賴后使用 ts-node 命令執(zhí)行 ts 文件即可。

1.在命令行安裝依賴

npm install typescript ts-node

2.使用 ts-node 運(yùn)行 ts 文件(這里使用 npx 來執(zhí)行 ts-node,因?yàn)?ts-node 是在本地項(xiàng)目中安裝的,如果直接使用的話會報命令找不到的錯誤,當(dāng)然如果在全局安裝了 ts-node npm 包就直接可以使用 ts-node 來運(yùn)行,如果只是本地安裝了,那么需要加上 npx,這是會到 node_modules 文件夾中找到 ts-node 包來進(jìn)行執(zhí)行。)

全局安裝了: ts-node: ts-node xxx.ts
本地項(xiàng)目安裝了 ts-node: npx ts-node xxx.ts

補(bǔ)充: ts-node 也可以直接在命令行中編寫和執(zhí)行 ts 代碼,像 python 那樣,

如下圖:

ts-node.png

2. tsc

tsc 顧名思義就是 typescript 的編譯器名稱,在安裝完 typescript 后,即可以使用 tsc 命令執(zhí)行 ts 文件,當(dāng)然不同于 ts-node 能夠直接運(yùn)行 ts 文件,tsc 只是將 ts 文件編譯后輸出成 js 文件,然后可以再通過 node 來執(zhí)行生成的 js 文件。

tsc 有許多的配置項(xiàng),當(dāng)運(yùn)行 tsc --init 時可以在項(xiàng)目中生成 tsconfig.json 文件,這個文件里面包含了許多的配置,包括配置編譯后的文件輸出路徑,編譯后的文件用哪種模塊規(guī)范以及兼容 es6 語法等等選項(xiàng)。

//1.安裝 typescript
npm install typescript

//2.使用 tsc 生成 tsconfig.json 文件
npx tsc --init

//3.使用 tsc 編譯 ts 文件
npx tsc xxx.ts

TypeScript 中的函數(shù)重載

TS 中的函數(shù)重載并不像其它語言中的函數(shù)重載一樣,和其它語言如 Java 比起來,更像是一種偽重載,它不能像 Java 中重載那樣實(shí)現(xiàn)同樣的函數(shù)名,但是參數(shù)個數(shù)不一樣,而是更多的為類型推斷服務(wù)。

簡單的排序算法

首先,使用 TS 來實(shí)現(xiàn)一個快速排序函數(shù):

1. 快速排序

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))
}

上面這段代碼是使用泛型實(shí)現(xiàn)的快速排序函數(shù),快速排序比冒泡排序的性能要好很多,基本思想就是分治(divide and conquer),簡單來說就是先選一個元素作為中間數(shù),然后分成兩部分,小于這個元素的部分,和大于這個元素部分,接著再使用遞歸分別進(jìn)行處理這兩部分,將排序任務(wù)分解到最小,然后再合并。

上面代碼中的快速排序方式,如果傳遞的是英文數(shù)組那就沒問題,但是如果傳遞的是中文數(shù)組,那就不能正常排序了,所以中文數(shù)組需要單獨(dú)進(jìn)行處理,使用下面的函數(shù):

2. 中文排序

// 通過正則表達(dá)式,判斷是否是中文數(shù)組
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')
    })
}

如果是中文數(shù)組,那么使用數(shù)組內(nèi)置的 sort 函數(shù)進(jìn)行排序。

接下來,如果需要將英文數(shù)組中的每一項(xiàng)進(jìn)行排序,則還需要單獨(dú)的函數(shù)進(jìn)行處理:

3. 字符串自排序

// 英文自排序
function strSelfSort(str: string): string {
    const strArr = str.split('')
    return quickSort(strArr).join('')
}

實(shí)現(xiàn)英文字符串自排序就是先將字符串進(jìn)行 split 分割成字符數(shù)組,然后傳遞到之前寫的快速排序函數(shù)中,得到結(jié)果后再通過 join 函數(shù)拼接成字符串返回。

那么,接下來將上面的幾種排序功能整合成一個單獨(dú)的通用函數(shù):

4. 通過泛型整合幾種排序

// 通用的排序函數(shù)
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}`)
}

通過上面的通用排序函數(shù)可以看出,在函數(shù)內(nèi)部通過排序傳遞的數(shù)據(jù)類型,如果是 string 則調(diào)用自排序,接著如果是數(shù)組的話,再判斷是否是中文數(shù)組,如果是,則調(diào)用中文數(shù)組排序函數(shù)進(jìn)行排序,不是的話就認(rèn)定為是英文數(shù)組,英文數(shù)組首先使用 map 函數(shù)遍歷,判斷數(shù)組中如果存在 string 類型就先調(diào)用字符串自排序函數(shù)進(jìn)行排序,否則就原樣返回,最后再通過快速排序函數(shù)進(jìn)行排序,這樣就完成了英文數(shù)組既每一項(xiàng)都排序了,整體數(shù)組也進(jìn)行了排序。

雖然上面的排序函數(shù)功能已經(jīng)比較完善了,但是有一點(diǎn)不太好的地方就是這個函數(shù)返回了一個聯(lián)合類型 T[] | string,這樣就會導(dǎo)致通過這個函數(shù)排序的結(jié)果不能確切的推斷出具體的類型,而只能是個聯(lián)合類型,那么我們也只能使用這個聯(lián)合類型里共有的方法提示,

如下圖:

image.png

image.png

這里簡單的調(diào)用了一下寫好的排序函數(shù),返回的結(jié)果類型竟然是:string | string[][] 的聯(lián)合類型,這樣的返回結(jié)果對于開發(fā)后續(xù)功能來說很不友好,那么接下來,就使用 TS 中的函數(shù)重載來完善一下上面的排序函數(shù):

5. 使用函數(shù)重載完善排序功能

// 使用函數(shù)重載重構(gòu)排序函數(shù)
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}`)
}

關(guān)于 TS 的函數(shù)重載,就是只有一個實(shí)現(xiàn)的函數(shù),其余都是函數(shù)簽名,而且必須放在實(shí)現(xiàn)函數(shù)的上面,在調(diào)用這個函數(shù)的時候,只會顯示上面的函數(shù)簽名函數(shù),而不會展示具體實(shí)現(xiàn)的函數(shù),但是實(shí)際執(zhí)行的卻是那個實(shí)現(xiàn)函數(shù),在這種情況下,通過使用函數(shù)重載寫個兩個不同參數(shù)和返回值的函數(shù)簽名提供給調(diào)用者使用,而在具體實(shí)現(xiàn)函數(shù)中去兼容處理,這樣做的好處就是調(diào)用者得到的返回值類型可以是某個具體的類型了,而不再是個聯(lián)合類型,更有益于后面的開發(fā)。

總結(jié)

通過使用 TS 的函數(shù)重載解決了當(dāng)一個函數(shù)返回一個聯(lián)合類型時,類型推斷不確定的問題,在某些會返回聯(lián)合類型的場景下可以嘗試使用,方便后續(xù)的類型推斷操作,所以說,TS 的一切真的都是為類型而服務(wù)的,怎么寫好 TS 代碼其實(shí)就是在更好的完善類型推斷,類型系統(tǒng)的過程,只有更好更準(zhǔn)確的類型推斷,才能發(fā)揮 TS 的作用,讓編譯器在開發(fā)過程中智能的告訴開發(fā)者有哪些屬性和方法可以調(diào)用,并且在調(diào)用了錯誤的屬性和方法后可以及時提醒開發(fā)者。

到此這篇關(guān)于TypeScript 泛型重載函數(shù)的使用方式的文章就介紹到這了,更多相關(guān)TypeScript 泛型重載函數(shù) 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論