溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么在TypeScript中保護類型

發(fā)布時間:2021-04-29 15:47:44 來源:億速云 閱讀:116 作者:Leah 欄目:開發(fā)技術(shù)

怎么在TypeScript中保護類型?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

概述

在 TypeScript 中使用聯(lián)合類型時,往往會碰到這種尷尬的情況:

interface Bird {
  	// 獨有方法
    fly();
  	// 共有方法
    layEggs();
}

interface Fish {
  	// 獨有方法
    swim();
  	// 共有方法
    layEggs();
}

function getSmallPet(): Fish | Bird {
    // ...
}

let pet = getSmallPet();
pet.layEggs(); // 正常
pet.swim();    // ts 報錯

如上所示,getSmallPet函數(shù)中,既可以返回 Fish 類型的對象,又可以返回 Bird 類型的對象。由于返回的對象類型不確定,所以使用聯(lián)合類型對象共有的方法時,一切正常,但是使用聯(lián)合類型對象各自獨有的方法時,ts 會報錯。

那么如何解決這個問題呢?最粗暴的方法當(dāng)然是將聯(lián)合類型轉(zhuǎn)換為 any,不過這種方法不值得提倡,畢竟我們寫的是 TypeScript 而不是 AnyScript。

此時,我們使用今天的主角——類型保護,閃亮登場,它可以完美的解決這個問題。

孔乙己說過,茴香豆有四種寫法,同理,實現(xiàn)類型保護,也有四種寫法。

類型斷言

類型斷言是最常用的一種類型保護方法,即直接指定類型。由于,TypeScript 中識別的類型大多是靠 TypeScript 的自動類型推算算出來的,所以會出現(xiàn)上面所說的那種問題,即 TypeScript 不知道具體對象類型是什么,所以不確定有沒有聯(lián)合類型各自獨有的方法。

當(dāng)使用類型斷言直接指定類型時,相當(dāng)于你讓 TypeScript 開啟了上帝模式,可以直接知道具體類型是聯(lián)合類型中的那個,此時再使用對象的獨有方法就符合 TypeScript 的推斷了。

interface Bird {
  // 獨有方法
  fly();
  // 共有方法
  layEggs();
}

interface Fish {
  // 獨有方法
  swim();
  // 共有方法
  layEggs();
}

function getSmallPet(): Fish | Bird {
  // ...
}

let pet = getSmallPet();
pet.layEggs(); // 正常
// 通過鴨子類型來進(jìn)行判斷
if ((pet as Bird).fly) {
  // 類型斷言
  (pet as Bird).fly()
} else {
  // 類型斷言
  (pet as Fish).swim()
}

如果嫌棄通過 as 來進(jìn)行類型斷言不夠上流,還可以使用類泛型的寫法,即:

let pet = getSmallPet();
pet.layEggs(); // 正常
// 通過鴨子類型來進(jìn)行判斷
if ((<Bird>pet).fly) {
  (<Bird>pet).fly()
} else {
  (<Fish>pet).swim()
}

tips:友情提示,雖然使用類泛型寫法進(jìn)行類型斷言看起來高端一些,但是由于在 tsx 中語法存在歧義,所以為了統(tǒng)一起見,推薦使用 as 的方法進(jìn)行類型斷言。

in語法

在js中,我們經(jīng)常使用 in 語法來判斷指定的屬性是否在指定的對象或其原型鏈中。

同理,在 TypeScript 中,我們可以通過這種方法確認(rèn)對象類型。

interface Bird {
  // 獨有方法
  fly();
  // 共有方法
  layEggs();
}

interface Fish {
  // 獨有方法
  swim();
  // 共有方法
  layEggs();
}

function getSmallPet(): Fish | Bird {
  // ...
}

let pet = getSmallPet();
pet.layEggs(); // 正常
// 使用 in 語法進(jìn)行類型保護
if ('fly' in pet) {
  pet.fly()
} else {
  pet.swim()
}

原理同類型斷言一樣,都是引導(dǎo) TypeScript 的類型推斷,確定對象類型。

instanceof 語法

當(dāng)聯(lián)合類型中使用的是 class 而不是 interface 時,instanceof 語法就派上用場了,通過 instanceof 語法可以區(qū)分不同的 class 類型。

class Bird {
  // 獨有方法
  fly() {};
  // 共有方法
  layEggs() {};
}

class Fish {
  // 獨有方法
  swim() {};
  // 共有方法
  layEggs() {};
}

function getSmallPet(): Fish | Bird {
  // ...
}

let pet = getSmallPet();
pet.layEggs(); // 正常
// 使用 in 語法進(jìn)行
if (pet instanceof Bird) {
  pet.fly()
} else {
  pet.swim()
}

typeof 語法

typeof 語法不同于 in 語法以及 instanceof 語法,in 語法以及 instanceof 語法都是用來引導(dǎo)類型推斷進(jìn)行不同對象類型推斷,而 typeof 語法常用于基本類型的推斷(或者是聯(lián)合使用基本類型和對象類型)。

簡而言之,當(dāng)使用 typeof 能夠區(qū)分聯(lián)合類型中的不同類型時,即可使用它。

function getSmallPet(): number | string {
  // ...
}

let pet = getSmallPet();
if (typeof pet === 'number') {
  pet++
} else {
  pet = Number(pet) + 1
}

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI