2023-07-04 18:25:33來源:web前端開發(fā)
類型保護(hù)是一個(gè)執(zhí)行運(yùn)行時(shí)檢查的表達(dá)式,以保證某個(gè)范圍內(nèi)的類型。類型保護(hù)的一個(gè)典型應(yīng)用場(chǎng)景是縮小聯(lián)合類型的類型范圍。這是為了保證類型安全,即在運(yùn)行時(shí)安全地訪問特定類型對(duì)象中的特定屬性或方法。
在這篇文章中,我將介紹 5 種實(shí)現(xiàn)類型保護(hù)的方法。
(資料圖片)
首先我們來介紹一下比較常見的typeof類型防護(hù)。typeof 運(yùn)算符可以在運(yùn)行時(shí)獲取對(duì)象的類型,該運(yùn)算符返回以下可能的值:
"string""number""bigint""boolean""symbol""undefined""object""function"因此使用 typeof 運(yùn)算符,我們可以在運(yùn)行時(shí)獲取變量的實(shí)際類型。舉個(gè)例子:
function printId(id: string | number) { if (typeof id === "string") { console.log(`ID: ${id.toUpperCase()}`); } else if (typeof id === "number") { console.log(`ID: ${id}`); }}
在上面的代碼中,我們定義了一個(gè) printId 函數(shù),它包含一個(gè) id 參數(shù),其類型為字符串 | 數(shù)字聯(lián)合類型。
在函數(shù)體中,我們使用 typeof 運(yùn)算符來確定參數(shù)的實(shí)際類型。如果id參數(shù)是字符串類型,我們會(huì)將其值轉(zhuǎn)換為大寫后再輸出。
那么為什么要使用 typeof 運(yùn)算符來縮小 id 參數(shù)的類型呢?主要原因是為了保證運(yùn)行時(shí)的類型安全。例如,當(dāng)id參數(shù)的類型是數(shù)字類型時(shí),但是我們調(diào)用id.toUpperCase()方法,就會(huì)拋出運(yùn)行時(shí)異常。
在支持 TypeScript IntelliSense 的編輯器中,當(dāng)您訪問 id 參數(shù)的某些屬性時(shí),只能訪問字符串和數(shù)字類型的公共屬性。具體如下圖所示:
02、instanceof 類型守衛(wèi)雖然typeof運(yùn)算符可以區(qū)分不同的類型,但如果我們想判斷一個(gè)對(duì)象是否是某個(gè)類的實(shí)例,從而安全地訪問該實(shí)例上特有的屬性或方法,那么typeof運(yùn)算符就無能為力了。
對(duì)于這個(gè)需求,我們可以使用instanceof運(yùn)算符。再次,我們舉一個(gè)具體的例子:
class Shape { constructor(public id: string) {}}class Circle extends Shape { constructor( public id: string, public radius: number) { super(id); }}class Square extends Shape { constructor( public id: string, public sideLength: number) { super(id); }}
在上面的代碼中,我們定義了一個(gè)Shape類,并基于它創(chuàng)建了兩個(gè)子類。接下來,我們定義一個(gè) printShapeInfo 函數(shù)來打印有關(guān)不同形狀的信息:
function printShapeInfo(shape: Shape) { if (shape instanceof Circle) { console.log(`Circle"s radius is: ${shape.radius}`); } else if (shape instanceof Square) { console.log(`Square"s sideLength is: ${shape.sideLength}`); }}
在printShapeInfo函數(shù)體中,我們使用instanceof運(yùn)算符來縮小形狀參數(shù)的類型,從而輸出不同形狀的信息。在 if...else if 分支之外,我們只能訪問 Circle 對(duì)象和 Square 對(duì)象共有的 id 屬性。
03、in type guards對(duì)于前面使用instanceof運(yùn)算符實(shí)現(xiàn)類型保護(hù)的示例,我們還可以使用接口的形式來描述Shape、Circle和Square類型。
interface Shape { id: string;}interface Circle extends Shape { radius: number;}interface Square extends Shape { sideLength: number;}
由于TypeScript接口定義的類型在編譯后并不會(huì)生成對(duì)應(yīng)的類型,因此我們無法在運(yùn)行時(shí)使用instanceof運(yùn)算符進(jìn)行類型檢測(cè)。要實(shí)現(xiàn)printShapeInfo函數(shù)的功能,我們可以使用in運(yùn)算符,具體實(shí)現(xiàn)如下:
function printShapeInfo(shape: Shape) { if ("radius" in shape) { console.log(`Circle"s radius is: ${shape.radius}`); } else if ("sideLength" in shape) { console.log(`Square"s sideLength is: ${shape.sideLength}`); }}
除了上述方法之外,我們還可以使用可判別聯(lián)合類型來表示Shape類型:
type Circle = { id: string; type: "circle"; radius: number;};type Square = { id: string; type: "square"; sideLength: number;};type Shape = Circle | Square;
在Circle和Square類型中,type屬性的類型是字符串文字類型,用于區(qū)分不同的形狀,稱為可區(qū)分屬性。對(duì)于判別聯(lián)合類型,結(jié)合switch…case語(yǔ)句,我們還可以實(shí)現(xiàn)printShapeInfo函數(shù)對(duì)應(yīng)的功能。
function printShapeInfo(shape: Shape) { switch (shape.type) { case "circle": console.log(`Circle"s radius is: ${shape.radius}`); break; case "square": console.log(`Square"s sideLength is: ${shape.sideLength}`); break; default: console.log("Unknown shape"); }}
介紹完如何使用常見的 typeof、instanceof 和 in 運(yùn)算符實(shí)現(xiàn)類型保護(hù)之后,我們來介紹一下如何定義用戶自定義的類型保護(hù)。
04、用戶定義的類型保護(hù)為了演示用戶定義的類型保護(hù),讓我們重新定義 3 種類型:
interface Shape { id: string;}interface Circle extends Shape { radius: number;}interface Square extends Shape { sideLength: number;}
定義完Shape相關(guān)的類型后,我們來定義用戶自定義的類型保護(hù)函數(shù):
function isCircle(shape: Shape): shape is Circle { return "radius" in shape;}function isSquare(shape: Shape): shape is Square { return "sideLength" in shape;}
與普通函數(shù)相比,自定義類型保護(hù)函數(shù)返回類型謂詞。上面代碼中的 shape is Circle 就是所謂的類型謂詞。謂詞采用parameterName is Type 的形式,其中parameterName 必須是當(dāng)前函數(shù)簽名中的參數(shù)名稱。
這樣就可以理解isCircle用戶自定義類型保護(hù)函數(shù)的作用了。如果函數(shù)返回值為true,則shape參數(shù)的類型為Circle類型。
現(xiàn)在我們有了 isCircle 和 isSquare 函數(shù),我們可以在 printShapeInfo 函數(shù)中使用它們,如下所示:
function printShapeInfo(shape: Shape) { if (isCircle(shape)) { console.log(`Circle"s radius is: ${shape.radius}`); } else if (isSquare(shape)) { console.log(`Square"s sideLength is: ${shape.sideLength}`); }}
05、相等縮小類型防護(hù)除了前面描述的 4 種類型保護(hù)方法之外,TypeScript 還支持使用 if/switch 語(yǔ)句和相等檢查,例如 ===、!===、== 和 != 運(yùn)算符來縮小變量的類型。
function printValues(a: string | number, b: string | string[]) { if (a === b) { console.log(a.toUpperCase()); // (parameter) a: string console.log(b.toUpperCase()); // (parameter) b: string } else { console.log(a); // (parameter) a: string | number console.log(b); // (parameter) b: string | string[] }}
上面的代碼中,printValues函數(shù)支持a和b 2個(gè)參數(shù),并且它們的類型都是聯(lián)合類型。當(dāng)a===b表達(dá)式的計(jì)算結(jié)果為true時(shí),參數(shù)a和b的類型將縮小為字符串類型。當(dāng)然,使用!==運(yùn)算符也可以用來實(shí)現(xiàn)類型縮小。
function printValues2(a: string | number, b: string | string[]) { if (a !== b) { console.log(a); // (parameter) a: string | number console.log(b); // (parameter) b: string | string[] } else { console.log(a.toLowerCase()); // (parameter) a: string console.log(b.toLowerCase()); // (parameter) b: string }}
這就是關(guān)于 TypeScript 類型防護(hù)的全部?jī)?nèi)容。
總結(jié)以上就是我今天想與你分享的5個(gè)TS的知識(shí)技能,希望對(duì)你有所幫助。
關(guān)鍵詞:
類型保護(hù)是一個(gè)執(zhí)行運(yùn)行時(shí)檢查的表達(dá)式,以保證某個(gè)范圍內(nèi)的類型。類型
技術(shù)進(jìn)步有可能以驚人的速度顛覆商業(yè)模式。因此,企業(yè)領(lǐng)導(dǎo)者不可避免地
如果沒有適當(dāng)?shù)臄?shù)據(jù)測(cè)試,生產(chǎn)中的數(shù)據(jù)質(zhì)量就是不完整的。在本文中,您
在編寫測(cè)試時(shí),這些指導(dǎo)方針將作為要遵循的最佳實(shí)踐,這可以導(dǎo)致更高質(zhì)
在日益數(shù)字化的世界中,城市和市政當(dāng)局必須利用技術(shù)和數(shù)據(jù)來提高效率并
日前,“答卷”——長(zhǎng)沙師范學(xué)院音樂舞蹈學(xué)院2019級(jí)舞蹈學(xué)專業(yè)學(xué)生畢業(yè)
而狼隊(duì)第2輪首戰(zhàn)就是北京WB,相當(dāng)于是春季賽決賽重演,一上來強(qiáng)度就直
1、寵妻至上寵你一輩子幸福豬小妹娃娃王妃陪你去隱居腹黑是怎樣煉成的
1、展開3全部申請(qǐng)AppleID時(shí)頁(yè)面中顯示的需要填寫的電子郵件地址,如下
日前,中建五局長(zhǎng)沙機(jī)場(chǎng)改擴(kuò)建項(xiàng)目開展了主題黨日活動(dòng),組織項(xiàng)目全體員
直播吧7月4日訊在今天的NBA夏季聯(lián)賽加州經(jīng)典賽中,國(guó)王100-94戰(zhàn)勝勇士
原文作者:FernandoDoglio原文地址:https: itnext io the-3-best-monorepo-tools-for-2023-29
腦科學(xué)研究又進(jìn)一大步!來自普林斯頓的科學(xué)家最新宣布,他們已經(jīng)成功創(chuàng)
企業(yè)將業(yè)務(wù)從內(nèi)部部署設(shè)施遷移到云平臺(tái)需要大量時(shí)間、艱苦的工作和精心
近幾年,圖像生成領(lǐng)域取得了巨大的進(jìn)步,尤其是文本到圖像生成方面取得