1. 程式人生 > 程式設計 >TypeScript聯合型別,交叉型別和型別保護

TypeScript聯合型別,交叉型別和型別保護

目錄
  • 1.聯合型別
  • 2.交叉型別
  • 3.型別保護
    • 3.1自定義型別保護
    • 3.2typeof 型別保護
    • 3.3instanceof型別保護

1.聯合型別

所謂的聯合型別就是定義一些型別,定義的變數只需要滿足任意一種型別即可,聯合型別使用|定義,示例程式碼如下:

// 通過 | 符號定義聯合型別
let value: number | boolean | string = '一碗周'
value = 18

在上面的程式碼中我們定義了一個value變數,該變數可以是number、boolean或者string型別。

2.交叉型別

介紹了聯合型別,然後介紹一下與之特別相似的交叉型別。

所謂的交叉型別就是需要滿足所有型別,交叉型別使用&符號定義。

示例程式碼如下:

// 定義三個普通介面型別
interface Name {
  name: string
}
interface Age {
  age: number
}
interface Hobby {
  hobby: string
}
// 定義一個物件,該物件為上面三個物件的聯合型別
let person: Name & Age & Hobby = {
  // 如果少分配一個型別將會丟擲異常
  name: '一碗周',age: 18,hobby: 'coding',}

3.型別保護

現在我們有一個需求:獲取一個具有任意型別陣列中第一個數字。

實現程式碼如下:

// 定義一個包含number或者string的陣列
const arr: (number | string)[] = [1,'數字']
// 遍歷陣列返回第一個數字
const getValue: (arr: (number | string)[]) => number = (
  arr: (number | string)[],): number => {
  for (let i = 0; i < arr.length; i++) {
    // 如果當前值轉換為數字時候不是一個 NaN 則返回
    if mOCDBHAYzR(!isNaN(Number(arr[i]))) {
      return arr[i] // 不能將型別“string | number”分配給型別“number”。
    }
  }
}


上述程式碼中return時並不知道返回的是不是一個number型別。所以將會丟擲異常。

上述功能可以通過型別斷言來完成,示例程式碼如下:

const getValue: (arr: (number | string)[]) => number = (
  arr: (number | string)[],): number => {
  for (let i = 0; i < arr.length; i++) {
    // 如果當前值轉換為數字時候不是一個 NaN 則返回
    if (!isNaN(Number(arr[i]))) {
      return arr[i] as number // 告訴 編譯器 我返回的就是一個 number
    }
  }
}

什麼是型別斷言請參考:型別斷言

如果使用型別斷言來說明,如果想要的資料型別不一樣時,就會顯得比較繁瑣。這個時候就需要型別保護來完成該功能,

型別保護主要分為以下三種:

3.1自定義型別保護

自定義型別保護的方式就是定義一個函式,該函式是的返回結構是一個parameterName is type的形式,該形式是一個型別謂詞 。parameterName必須是來自於當前函式引數裡的一個引數名。

示例程式碼如下:

// 使用自定義型別保護
// 1. 定義一個函式 mOCDBHAYzR其返回值是一個 型別謂詞,即 parameterName is Type 也就是 引數名 is 型別 的形式
function isNumber(value: number | string): value is number {
  // 如果返回 true 則說明 傳入的 value 是 is 後面的type
  return !isNaN(Number(value))
}
// 2. 定義一個獲取數字的函式
const getNumber: (value: number | string) => number = (
  value: number | string,): number => {
  // 如果呼叫 isNumber 的值為 true 則說明 value 是一個數字,所以將數字返回
  if (isNumber(value)) {
    return value
  }
}
// 3. 呼叫獲取最終的數值
const getValue: (arr: (number | string)[]) => number = (
  arr: (number | string)[],): number => {
  for (let i = 0; i < arr.length; i++) {
    // 如果返回數字,轉換為 boolean 值為 true
    if (getNumber(arr[i]) || getNumber(arr[i]) === 0) {
      return getNumber(arr[i])
    }
  }
}

定義第二個函式的原因是在陣列中直接使用i作為返回值還是有問題的,所以定義一個函式過渡一下。

3.2typeof 型別保護

中的typeof關鍵字可以判斷當前型別,但是僅僅只能判斷numberstringbooleansymbol四種類型。

在這個需求中就足夠了,接下來我們看看如何通過typeof來實現型別保護。

示例程式碼如下:

// 1. 定義一個獲取數字的函式
const getNumber: (value: number | string) => number = (
  value: number | string,): number => {
  // 判斷當前是否為字串,如果是返回當前值
  if (typeof value === 'number') {
    return value
  }
}
// 2. 呼叫獲取最終的數值
const getValue: (arr: (number | string)[]) => number = (
  arr: (number | string)[],): number => {
  for (let i = 0; i < arr.length; i++) {
    // 如果返回數字,轉換為 boolean 值為 true
    if (getNumber(arr[i]) || getNumber(arr[i]) === 0) {
      return getNumber(arr[i])
    }
  }
}

3.3instanceof型別保護

instanceof操作符也是Script中提供的原生操作符,它用來判斷一個例項是不是某個建構函式建立的,或者是不是使用ES6語法的某個類建立的。在TypeScript中也可以通過instanceof操作符來實現型別保護,

示例程式碼如下:

/**
 * 由於 instanceof 僅僅支援引用型別,不支援原始型別,所以說這裡需要進行一下改動,將陣列修改為如下:
 */
const arr2: (Number | String)[] = [new String('彼岸繁華'),new Number(10)]
// 1. 定義一個獲取數字的函式
const getNumber: (value) => number = (value): number => {
  // 判斷當前是否為 Number 型別,將當前值轉換為字串返回
  if (value instanceof Number) {
    return Number(value)
  }
}
// 2. 呼叫獲取最終的數值
const getValue: (arr: (Number | String)www.cppcns.com[]) => number = (
  arr: (Number | String)[],): number => {
  for (let i = 0; i < arr.length; i++) {
    // 如果返回數字,轉換為 boolean 值為 true
    if (getNumber(arr[i]) || getNumber(arr[i]) === 0) {
      return getNumber(arr[i])
    }
  }
}


使用instanceof時需要注意一下兩點:

    http://www.cppcns.com
  • 只適應於任何引用型別,不支援原始型別。
  • 前者的原型鏈上是否 包含 後者的原型物件。

到此這篇關於TypeScript聯合型別,交叉型別和型別保護的文章就介紹到這了,更多相關TypeScript聯合型別.交叉型別,型別保護內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!