TypeScript中的交叉類型和聯合類型示例講解

在這裡插入圖片描述

交叉類型(Intersection types)

什麼事交叉類型呢?簡單來說就是通過&符號將多個類型進行合並成一個類型,然後用type來聲明新生成的類型。這裡我舉個例子,具體如下:

interface ClassA{
    name:string;
    age:number
}
interface ClassB{
    name:string;
    phone:number;
}

將接口ClassA和接口ClassB通過&進行合並創建一個新的接口類型Class

type Class = ClassA & ClassB
let info:Class = {
    name:'zhagsan',
    age:18,
    phone:1573875555
}

要點

任何類型都能通過&合並成新的類型嗎?

  • 這肯定是不行的,原子類型進行合並是沒有任何意義,因為它們合並後的類型是never,比如string&number,這肯定是錯誤的,因為不可能有既滿足字符串又滿足數字類型。

合並的接口類型中具有同名屬性,該怎麼處理?

  • 這裡分兩種情況,如果同名屬性的類型相同則合並後還是原本類型,如果類型不同,則合並後類型為never
interface X{
	q:number,
	w:string
}
interface Y{
	q:boolean,
	r:string,
}
type XY = X&Y

編輯器中直接就給我們瞭提示,如下圖所示:

在這裡插入圖片描述

再舉一個稍微復雜點的例子

interface A {
    inner: D;
}
interface B {
    inner: E;
}
interface C {
    inner: F;
}

interface D {
    d: boolean;
}
interface E {
    e: string;
}
interface F {
    f: number;
}
type ABC = A & B & C;
let abc: ABC = {
    inner: {
        d: false,
        e: 'className',
        f: 5
    }
};

聯合類型(Union types)

聯合類型和交叉類型比較相似,聯合類型通過|符號連接多個類型從而生成新的類型。它主要是取多個類型的交集,即多個類型共有的類型才是聯合類型最終的類型。聯合類型可以是多個類型其中一個,可做選擇,比如:string | number,它的取值可以是string類型也可以是number類型。
舉幾個例子,如下所示:

  • 聲明變量的時候設置變量類型
let a:string|number|boolean;
a = 's';
a = 1;
a= false;
  • 多個接口類型進行聯合
interface X{
	q:number,
	w:string,
	r:string
}
interface Y{
	q:number
	r:string,
}
type XY = X | Y
let value:XY = {
    q:1,
    r:'r'
}
  • 函數接口類型進行聯合
interface X{
	x:()=>string;
	y:()=>Number;
}
interface Y{
	x:()=>string;
}
type XY = X|Y;
function func1():XY{
//此處不進行類型斷言為XY在編輯器中會報類型錯誤
  return {} as XY

}
let testFunc = func1();
testFunc.x();
testFunc.y(); //Error:類型“XY”上不存在屬性“y”,類型“Y”上不存在屬性“y”。

另外我們還要註意,testFunc.x()還會報類型錯誤,我們需要用類型守衛來區分不同類型。這裡我們用in操作符來判斷

if('x' in testFunc) testFunc.x()

類型縮減

  • 當字面量類型和原始類型進行聯合,那麼就會造成類型縮減。
type A = 'a' | string;  //string類型
type B = false | boolean; //bolean 類型
type C = 1 | number; //number類型
  • 當然枚舉也會有類型縮減現象,如下:
enum Class{
   A,
   B
 }
type C = Class.A | Class;//Class類型

我們發現:TS會把字面量類型和枚舉成員類型給縮減掉,隻剩下原始類型和枚舉類型
🤔思考一個問題:當接口類型進行聯合,接口中同名屬性的類型不同,該怎麼進行縮減呢?比如下面的例子,看到這裡的話,如果你知道答案寫在評論區。

interface A{
   name:string
}
interface B{
   name:string | number
   [property:string]:any
}
type AB = A|B

到此這篇關於TypeScript交叉類型和聯合類型的文章就介紹到這瞭,更多相關TS交叉類型與聯合類型內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: