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

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

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

前言

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

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

1. ts-node

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

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

1.在命令行安裝依賴(lài)

npm install typescript ts-node

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

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

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

如下圖:

ts-node.png

2. tsc

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

tsc 有許多的配置項(xiàng),當(dāng)運(yùn)行 tsc --init 時(shí)可以在項(xiàng)目中生成 tsconfig.json 文件,這個(gè)文件里面包含了許多的配置,包括配置編譯后的文件輸出路徑,編譯后的文件用哪種模塊規(guī)范以及兼容 es6 語(yǔ)法等等選項(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ù)重載并不像其它語(yǔ)言中的函數(shù)重載一樣,和其它語(yǔ)言如 Java 比起來(lái),更像是一種偽重載,它不能像 Java 中重載那樣實(shí)現(xiàn)同樣的函數(shù)名,但是參數(shù)個(gè)數(shù)不一樣,而是更多的為類(lèi)型推斷服務(wù)。

簡(jiǎn)單的排序算法

首先,使用 TS 來(lái)實(shí)現(xiàn)一個(gè)快速排序函數(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),簡(jiǎn)單來(lái)說(shuō)就是先選一個(gè)元素作為中間數(shù),然后分成兩部分,小于這個(gè)元素的部分,和大于這個(gè)元素部分,接著再使用遞歸分別進(jìn)行處理這兩部分,將排序任務(wù)分解到最小,然后再合并。

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

2. 中文排序

// 通過(guò)正則表達(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)行排序。

接下來(lái),如果需要將英文數(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ù)組,然后傳遞到之前寫(xiě)的快速排序函數(shù)中,得到結(jié)果后再通過(guò) join 函數(shù)拼接成字符串返回。

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

4. 通過(guò)泛型整合幾種排序

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

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

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

如下圖:

image.png

image.png

這里簡(jiǎn)單的調(diào)用了一下寫(xiě)好的排序函數(shù),返回的結(jié)果類(lèi)型竟然是:string | string[][] 的聯(lián)合類(lèi)型,這樣的返回結(jié)果對(duì)于開(kāi)發(fā)后續(xù)功能來(lái)說(shuō)很不友好,那么接下來(lái),就使用 TS 中的函數(shù)重載來(lái)完善一下上面的排序函數(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ù)重載,就是只有一個(gè)實(shí)現(xiàn)的函數(shù),其余都是函數(shù)簽名,而且必須放在實(shí)現(xiàn)函數(shù)的上面,在調(diào)用這個(gè)函數(shù)的時(shí)候,只會(huì)顯示上面的函數(shù)簽名函數(shù),而不會(huì)展示具體實(shí)現(xiàn)的函數(shù),但是實(shí)際執(zhí)行的卻是那個(gè)實(shí)現(xiàn)函數(shù),在這種情況下,通過(guò)使用函數(shù)重載寫(xiě)個(gè)兩個(gè)不同參數(shù)和返回值的函數(shù)簽名提供給調(diào)用者使用,而在具體實(shí)現(xiàn)函數(shù)中去兼容處理,這樣做的好處就是調(diào)用者得到的返回值類(lèi)型可以是某個(gè)具體的類(lèi)型了,而不再是個(gè)聯(lián)合類(lèi)型,更有益于后面的開(kāi)發(fā)。

總結(jié)

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

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

相關(guān)文章

最新評(píng)論