最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解TypeScript2.0標記聯(lián)合類型

 更新時間:2021年05月07日 10:36:23   作者:淺笑·  
這篇文章主要介紹了TypeScript2.0標記聯(lián)合類型,對TS感興趣的同學,可以參考下

使用標記的聯(lián)合類型構建付款方式

假設咱們?yōu)橄到y(tǒng)用戶可以選擇的以下支付方式建模

  • Cash (現(xiàn)金)
  • PayPal 與給定的電子郵件地址
  • Credit card 帶有給定卡號和安全碼

對于這些支付方法,咱們可以創(chuàng)建一個 TypeScript 接口

interface Cash {
  kind: "cash";
}

interface PayPal {
  kind: "paypal",
  email: string;
}

interface CreditCard {
  kind: "credit";
  cardNumber: string;
  securityCode: string;
}

注意,除了必需的信息外,每種類型都有一個kind屬性,即所謂的判別屬性。這里每種情況都是字符串字面量類型。

現(xiàn)在定義一個PaymentMethod類型,它是我們剛才定義的三種類型的并集。通過這種方式,用聲明PaymentMethod每個變量, 必須具有給定的三種組成類型中的一種:

type PaymentMethod = Cash | PayPal | CreditCard;

現(xiàn)在我們的類型已經(jīng)就緒,來編寫一個函數(shù)來接受付款方法并返回一個讀得懂的話語:

function describePaymentMethod(method: PaymentMethod) {
  switch (method.kind) {
    case "cash":
      // Here, method has type Cash
      return "Cash";

    case "paypal":
      // Here, method has type PayPal
      return `PayPal (${method.email})`;

    case "credit":
      // Here, method has type CreditCard
      return `Credit card (${method.cardNumber})`;
  }
}

首先,該函數(shù)包含的類型注釋很少,method參數(shù)僅包含一個。除此之外,函數(shù)基本是純 ES2015代碼。

在switch語句的每個case中,TypeScript 編譯器將聯(lián)合類型縮小到它的一個成員類型。例如,當匹配到"paypal",method參數(shù)的類型從PaymentMethod縮小到PayPal。因此,咱們可以訪問email屬性,而不必添加類型斷言。

本質上,編譯器跟蹤程序控制流以縮小標記聯(lián)合類型。除了switch語句之外,它還要考慮條件以及賦值和返回的影響。

function describePaymentMethod(method: PaymentMethod) {
  if (method.kind === "cash") {
    // Here, method has type Cash
    return "Cash";
  }

  // Here, method has type PayPal | CreditCard

  if (method.kind === "paypal") {
    // Here, method has type PayPal
    return `PayPal (${method.email})`;
  }

  // Here, method has type CreditCard
  return `Credit card (${method.cardNumber})`;
}

控制流的類型分析使得使用標記聯(lián)合類型非常順利。使用最少的 TypeScript語法開銷,咱可以編寫幾乎純js,并且仍然可以從類型檢查和代碼完成中受益。

使用標記聯(lián)合類型構建 Redux 操作

標記聯(lián)合類型真正發(fā)揮作用的用例是在 TypeScript 應用程序中使用Redux時。 編寫一個事例,其中包括一個模型,兩個actions和一個Todo應用程序的reducer。

以下是一個簡化的Todo類型,它表示單個todo。這里使用readonly修飾符為了防止屬性被修改。

interface Todo {
  readonly text: string;
  readonly done: boolean;
}

用戶可以添加新的 todos 并切換現(xiàn)有 todos 的完成狀態(tài)。根據(jù)這些需求,咱們需要兩個Redux操作,如下所示:

interface AddTodo {
  type: "ADD_TODO";
  text: string;
}

interface ToggleTodo {
  type: "TOGGLE_TODO";
  index: number
}

與前面的示例一樣,現(xiàn)在可以將Redux操作構建為應用程序支持的所有操作的聯(lián)合

type ReduxAction = AddTodo | ToggleTodo;

在本例中,type屬性充當判別屬性,并遵循Redux中常見的命名模式?,F(xiàn)在添加一個與這兩個action一起工作的Reducer:

function todosReducer(
  state: ReadonlyArray<Todo> = [],
  action: ReduxAction
): ReadonlyArray<Todo> {
  switch (action.type) {
    case "ADD_TODO":
      // action has type AddTodo here
      return [...state, { text: action.text, done: false }];

    case "TOGGLE_TODO":
      // action has type ToggleTodo here
      return state.map((todo, index) => {
        if (index !== action.index) {
          return todo;
        }

        return {
          text: todo.text,
          done: !todo.done
        };
      });

    default:
      return state;
  }
}

同樣,只有函數(shù)簽名包含類型注釋。代碼的其余部分是純 ES2015,而不是特定于 TypeScript。

我們遵循與前面示例相同的邏輯?;赗edux操作的type屬性,我們在不修改現(xiàn)有狀態(tài)的情況下計算新狀態(tài)。在switch語句的情況下,我們可以訪問特定于每個操作類型的text和index屬性,而不需要任何類型斷言。

never 類型

TypeScript 2.0引入了一個新原始類型never。never類型表示值的類型從不出現(xiàn)。具體而言,never是永不返回函數(shù)的返回類型,也是變量在類型保護中永不為true的類型。

這些是never類型的確切特征,如下所述:

  • never是所有類型的子類型并且可以賦值給所有類型。
  • 沒有類型是never的子類型或能賦值給never(never類型本身除外)。
  • 在函數(shù)表達式或箭頭函數(shù)沒有返回類型注解時,如果函數(shù)沒有return語句,或者只有never類型表達式的return語句,并且如果函數(shù)是不可執(zhí)行到終點的(例如通過控制流分析決定的),則推斷函數(shù)的返回類型是never。
  • 在有明確never返回類型注解的函數(shù)中,所有return語句(如果有的話)必須有never類型的表達式并且函數(shù)的終點必須是不可執(zhí)行的。

聽得云里霧里的,接下來,用幾個例子來講講never這位大哥。

永不返回的函數(shù)

下面是一個永不返回的函數(shù)示例:

// Type () => never
const sing = function() {
  while (true) {
    console.log("我就是不返回值,怎么滴!");
    console.log("我就是不返回值,怎么滴!");
    console.log("我就是不返回值,怎么滴!");
    console.log("我就是不返回值,怎么滴!");
    console.log("我就是不返回值,怎么滴!");
    console.log("我就是不返回值,怎么滴!");
  }
}

該函數(shù)由一個不包含break或return語句的無限循環(huán)組成,所以無法跳出循環(huán)。因此,推斷函數(shù)的返回類型是never。

類似地,下面函數(shù)的返回類型被推斷為never

// Type (message: string) => never
const failwith = (message: string) => {
  throw new Error(message);
};

TypeScript 推斷出never類型,因為該函數(shù)既沒有返回類型注釋,也沒有可到達的端點(由控制流分析決定)。

不可能有該類型的變量

另一種情況是,never類型被推斷為從不為ture。在下面的示例中,我們檢查value參數(shù)是否同時是字符串和數(shù)字,這是不可能的。

function impossibleTypeGuard(value: any) {
  if (
    typeof value === "string" &&
    typeof value === "number"
  ) {
    value; // Type never
  }
}

這個例子顯然是過于作,來看一個更實際的用例。下面的示例展示了 TypeScript 的控制流分析縮小了類型守衛(wèi)下變量的聯(lián)合類型。直觀地說,類型檢查器知道,一旦咱們檢查了value是字符串,它就不能是數(shù)字,反之亦然

function controlFlowAnalysisWithNever(
  value: string | number
) {
  if (typeof value === "string") {
    value; // Type string
  } else if (typeof value === "number") {
    value; // Type number
  } else {
    value; // Type never
  }
}

注意,在最后一個else分支中,value既不能是字符串,也不能是數(shù)字。在這種情況下,TypeScript 推斷出never類型,因為咱們已經(jīng)將value參數(shù)注解為類型為string | number,也就是說,除了string或number,value參數(shù)不可能有其他類型。

一旦控制流分析排除了string和number作為value類型的候選項,類型檢查器就推斷出never類型,這是惟一剩下的可能性。但是,咱們也就不能對value做任何有用的事情,因為它的類型是never,所以咱們的編輯器工具不會顯示自動顯示提示該值有哪些方法或者屬性可用。

never 和 void 之間的區(qū)別

你可能會問,為什么 TypeScript 已經(jīng)有一個void類型為啥還需要never類型。雖然這兩者看起來很相似,但它們是兩個不同的概念:

沒有顯式返回值的函數(shù)將隱式返回undefined。雖然我們通常會說這樣的函數(shù)“不返回任何東西”,但它會返回。在這些情況下,我們通常忽略返回值。這樣的函數(shù)在 TypeScript 中被推斷為有一個void返回類型。

具有never返回類型的函數(shù)永不返回。它也不返回undefined。該函數(shù)沒有正常的完成,這意味著它會拋出一個錯誤,或者根本不會完成運行。

函數(shù)聲明的類型推斷

關于函數(shù)聲明的返回類型推斷有一個小問題。咱們前面列出的幾條never特征,你會發(fā)現(xiàn)下面這句話:

在函數(shù)表達式或箭頭函數(shù)沒有返回類型注解時,如果函數(shù)沒有return語句,或者只有never類型表達式的return語句,并且如果函數(shù)是不可執(zhí)行到終點的(例如通過控制流分析決定的),則推斷函數(shù)的返回類型是never。

它提到了函數(shù)表達式和箭頭函數(shù),但沒有提到函數(shù)聲明。也就是說,為函數(shù)表達式推斷的返回類型可能與為函數(shù)聲明推斷的返回類型不同:

// Return type: void
function failwith1(message: string) {
  throw new Error(message);
}

// Return type: never
const failwith2 = function(message: string) {
  throw new Error(message);
};

這種行為的原因是向后兼容性,如下所述。如果希望函數(shù)聲明的返回類型never,則可以對其進行顯式注釋:

function failwith1(message: string): never {
  throw new Error(message);
}

以上就是詳解TypeScript2.0標記聯(lián)合類型的詳細內容,更多關于TS2.0標記聯(lián)合類型的資料請關注腳本之家其它相關文章!

相關文章

  • 網(wǎng)站基于flash實現(xiàn)的Banner圖切換效果代碼

    網(wǎng)站基于flash實現(xiàn)的Banner圖切換效果代碼

    這篇文章主要介紹了網(wǎng)站基于flash實現(xiàn)的Banner圖切換效果代碼,是基于Flash與js實現(xiàn)的banner圖片自動定時切換特效,并附有完整的示例源碼,非常具有實用價值,需要的朋友可以參考下
    2014-10-10
  • js和jquery實現(xiàn)tab狀態(tài)欄切換效果

    js和jquery實現(xiàn)tab狀態(tài)欄切換效果

    這篇文章主要為大家詳細介紹了js和jquery實現(xiàn)tab狀態(tài)欄切換效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 元素綁定click點擊事件方法

    元素綁定click點擊事件方法

    當點擊元素時,會發(fā)生 click 事件。當鼠標指針停留在元素上方,然后按下并松開鼠標左鍵時,就會發(fā)生一次 click。click() 方法觸發(fā) click 事件,或規(guī)定當發(fā)生 click 事件時運行的函數(shù)。
    2015-06-06
  • JS實現(xiàn)多物體緩沖運動實例代碼

    JS實現(xiàn)多物體緩沖運動實例代碼

    這篇文章主要介紹了JS實現(xiàn)多物體緩沖運動實例代碼,有需要的朋友可以參考一下
    2013-11-11
  • 詳談JavaScript 匿名函數(shù)及閉包

    詳談JavaScript 匿名函數(shù)及閉包

    本文詳細介紹了匿名函數(shù)、閉包、并給出了詳細的例子以及詳細的注意事項,是篇非常非常不錯的文章,推薦給大家。
    2014-11-11
  • Redux中間件redux-thunk使用詳解

    Redux中間件redux-thunk使用詳解

    redux-thunk是一種用于緩存異步數(shù)據(jù)的工具,能夠優(yōu)化頁面性能并提升加載速度,它通過緩存接口數(shù)據(jù),使多個頁面復用數(shù)據(jù),避免多次調用接口,解決異步操作帶來的性能問題,使用redux-thunk可以簡化中間件集成,提升應用運行效率
    2025-09-09
  • 原生JS實現(xiàn)煙花效果

    原生JS實現(xiàn)煙花效果

    這篇文章主要為大家詳細介紹了原生JS實現(xiàn)煙花效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • 利用JavaScript實現(xiàn)ISO周日歷

    利用JavaScript實現(xiàn)ISO周日歷

    周日歷是日常生活中不常用到的歷法系統(tǒng),一般用于政府、商務的會計年度或者學校教學日歷中。本文將利用JavaScript制作個簡單的周日歷,感興趣的可嘗試一下
    2022-07-07
  • js判斷圖片加載完成后獲取圖片實際寬高的方法

    js判斷圖片加載完成后獲取圖片實際寬高的方法

    這篇文章主要介紹了js判斷圖片加載完成后獲取圖片實際寬高的方法,涉及JavaScript圖片加載及屬性操作相關技巧,需要的朋友可以參考下
    2016-02-02

最新評論

昭平县| 正镶白旗| 桐庐县| 景德镇市| 虎林市| 德江县| 辛集市| 松原市| 六安市| 东乌珠穆沁旗| 南充市| 新龙县| 大安市| 新龙县| 兴化市| 阳高县| 九台市| 彭山县| 盐津县| 卫辉市| 西吉县| 九江市| 华池县| 阿尔山市| 达拉特旗| 石棉县| 乌兰浩特市| 田林县| 洛隆县| 博客| 如东县| 巴中市| 阿城市| 青州市| 云浮市| 双峰县| 广元市| 赤壁市| 鹰潭市| 大关县| 凉城县|