本文將簡述類型系統中的類型聯合,通俗的來說就是將一個變量規定為不是某一個類型,而是某些類型,我們在日常開發中很常見下面會給出例子。
值類型
在JavaScript中用const聲明的變量是不可以再次賦值的,也就是常量。在TypeScript中也可以用一個值來約束變量,作用其實和const聲明的變量差不多。
let a: "abc" = "abc";
a = "def" // 報錯 不能將類型“def”分配給“abc”
這個例子表明:a變量的類型是字符串“abc”,導致這個變量只能賦值為"abc",賦值其他字符串就會報錯。
在TypeScript中,如果遇到const聲明的變量并且沒有進行類型約束,那么就會將其識別為值類型。
const x = "hello"
x = "hi" // 報錯 無法分配到"x" 因為是常量
這樣推斷是合理的,因為const
命令聲明的變量,一旦聲明就不能改變,相當于常量。值類型就意味著不能賦為其他值。
注意:用const聲明的變量,如果賦值為對象并不會推斷為值類型,因為在JavaScript中對象的屬性是可以改變的
在日常開發中,單個值類型的作用不大也不常用,往往是將多個值類型聯合起來使用。
聯合類型
聯合類型是指:多個類型組成一個新的類型,多個類型之間用符號 | 連接
聯合類型A | B表示:必須滿足類型A或者類型B。
let x: number | string
x = 2
x = "123"
此時的x既可以是number類型,也可以是string類型。
聯合類型也可以和值類型相結合,舉一個很簡單的例子:
let sex: "男"|"女"
性別只能是男或者女,這樣用值類型和聯合類型相結合進行的約束,這樣可以清楚的規定好變量的取值范圍,不至于犯錯。當然也可以將null和undefined類型聯合進去。
當我們是用聯合類型時,要注意類型縮小的問題:
function parse(s: string | number) {console.log(s.toUpperCase()) // 報錯 類型“number”上不存在屬性“toUpperCase”
}
此時我們需要在函數內部將類型縮小
function parse(s: string | number) {if (typeof s === "string") {console.log(s.toUpperCase());} else {console.log(s);}
}
?交叉類型
交叉類型也是將多個類型組合為一個新的類型,類型之間用 & 連接。
A&B 表示必須同時滿足A類型和B類型。
交叉類型主要用于對象之間的組合。
let a :{x:number}&{y: string}a = {x: 1,y: "2"
}
變量a必須同事滿足兩個類型才可以成功賦值。
類型別名 type
類型別名是定義一個類型的關鍵字,將類型定義好之后,不同的地方約束類型的時候可以復用,減少代碼的冗余。
type
命令用來定義一個類型的別名。
type Person = {name: stringage: numbersex: "男" | "女"job: string
}let Tom: Person = {name: "Tom",age: 20,sex: "男",job: "外賣小哥"
}
別名可以讓類型的名字變得更有意義,也能增加代碼的可讀性,還可以使復雜類型用起來更方便,便于以后修改變量的類型。(類型別名不可以重名!!!)
type定義的類型別名是類型相關的代碼,在編譯為JavaScript之后就會全部消失。
其他常用類型
void: 通常用于函數的返回值,表示函數沒有任何返回值
never 通常用于約束函數的返回值,表示函數永遠不會結束