首頁 > 軟體

TypeScript中的交叉型別和聯合型別範例講解

2022-12-31 14:00:10

交叉型別(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會把字面量型別和列舉元型別給縮減掉,只剩下原始型別和列舉型別


IT145.com E-mail:sddin#qq.com