typescript不能不掌握的高級特性(一)

引言

在當前這個typescript火的一塌糊塗的時候,掌握typescript的一些高級用法,對咱們開發出高質量的代碼尤其重要。接下來的一段時間,筆者將會採用實例的方式向你們講述typescript的一些高級用法。本期要講述的是typescript裏面的交叉類型&。typescript

定義

官方對交叉類型的解析一如既往的官方!!!編輯器

交叉類型是將多個類型合併爲一個類型。 這讓咱們能夠把現有的多種類型疊加到一塊兒成爲一種類型,它包含了所需的全部類型的特性。 例如, Person & Serializable & Loggable 同時是 Person 和 Serializable 和 Loggable。 就是說這個類型的對象同時擁有了這三種類型的成員。函數

舉個栗子

iUserInfo 類型對象將擁有 iName 和 iBaseInfo 兩個類型的全部成員。ui

interface iName {
  firstName: string;
  lastName: string;
}

interface iBaseInfo {
  sex: 'male' | 'female';
  age: number;
}

type iUserInfo = iName & iBaseInfo;
const user: iUserInfo = {
  firstName: 'Jack',
  lastName: 'Ma',
  sex: 'male',
  age: 40,
};
複製代碼

類型成員衝突處理

當類型存在衝突的時候,成員之間會繼續合併,好比:spa

interface iProps1 {
  size: string;
}
interface iProps2 {
  size: number;
}
type iProps = iProps1 & iProps2;
let props: iProps = {
  size: 'ddd',
};
複製代碼

合併後 iProps 將以下:code

type iProps = {
  size: string & number;
};
複製代碼

顯然,string & number 這種類型是不存在的,因此等價於cdn

type iProps = {
  size: never;
};
複製代碼

因此編輯器報紅,就很容易解析了。對象

咱們這裏定義了 never 類型,never 類型是什麼呢?blog

never 類型

下面看官方文檔的解析ip

never 類型表示的是那些永不存在的值的類型。 例如, never 類型是那些老是會拋出異常或根本就不會有返回值的函數表達式或箭頭函數表達式的返回值類型; 變量也多是 never 類型,當它們被永不爲真的類型保護所約束時。 never 類型是任何類型的子類型,也能夠賦值給任何類型;然而,沒有類型是 never 的子類型或能夠賦值給 never 類型(除了 never 自己以外)。 即便 any 也不能夠賦值給 never。

初步看來,貌似沒有用!以前我也一度是這麼認爲的,其實它的做用仍是很大的! 舉個栗子,當你有一個聯合類型:

type AllType = 'a' | 'b';
複製代碼

在 switch 當中判斷 type,TS 是能夠收窄類型的 (discriminated union):

function handleValue(val: AllType) {
  switch (val) {
    case 'a':
      // val 在這裏收窄爲 'a'
      break;
    case 'b':
      // val 在這裏收窄爲 'b'
      break;
    default:
      // val 在這裏收窄爲 never
      const exhaustiveCheck: never = val;
      break;
  }
}
複製代碼

注意在 default 裏面咱們把被收窄爲 never 的 val 賦值給一個顯式聲明爲 never 的變量。若是一切邏輯正確,那麼這裏應該可以編譯經過。 可是假如後來有一天你修改了 AllType 的類型:

type AllType = 'a' | 'b' | 'c';
複製代碼

若是忘記了在 handleValue 裏面加上針對 'c' 的處理邏輯,這個時候在 default 裏面 val 會被收窄爲 'c',致使沒法賦值給 never,產生一個錯誤。

因此經過這個辦法,你能夠確保 handleValue 老是窮盡了全部 AllType 的可能類型。

@Author: WaterMan

相關文章
相關標籤/搜索