TypeScript 交叉類型
本節起開始介紹 TypeScript 高級類型,依次是交叉類型、聯合類型、類型別名、索引類型、映射類型、條件類型。
本節介紹交叉類型的語法和應用,跟數學集合里的相交不一樣,TypeScript 的交叉類型并不是指每個類型的交集,&
的意思理解成 and
,A & B
表示同時包含 A
和 B
的結果。
1. 慕課解釋
交叉類型是將多個類型合并為一個類型。
這讓我們可以把現有的多種類型疊加到一起成為一種類型,它包含了所需的所有類型的特性。
語法為:類型一 & 類型二
。
2. 簡單示例
先來看一個簡單示例:
interface Admin {
id: number,
administrator: string,
timestamp: string
}
interface User {
id: number,
groups: number[],
createLog: (id: number) => void,
timestamp: number
}
let t: Admin & User
t!.administrator // 合法 Admin.administrator: string
t!.groups // 合法 User.groups: number[]
t!.id // 合法 id: number
t!.timestamp // 合法 timestamp: never
代碼解釋: 交叉類型 Admin & User
包含了原類型的所有屬性,但是要注意兩個接口都擁有 id 和 timestamp 屬性,且 id 類型相同,timestamp 類型不同。在此交叉類型中,timestamp 屬性類型沖突,不可被賦值。
3. 應用場景
我們大多是在混入(Mixins)或其它不適合典型面向對象模型的地方看到交叉類型的使用。下面是合并兩傳入對象的成員屬性的例子:
function extend<T, U>(first: T, second: U): T & U {
for(const key in second) {
(first as T & U)[key] = second[key] as any
}
return first as T & U
}
函數返回結果的類型是兩個對象的交叉類型。調用 extend 函數,實現兩個對象的合并:
class Person {
constructor(public name: string) { }
}
class ConsoleLogger {
log() {}
}
let jim = extend(new Person('Jim'), new ConsoleLogger())
let n = jim.name
jim.log()
代碼解釋:
通過 extend()
函數合并了兩個類的實例,我們知道交叉類型是 and
的意思,那么合并后即可訪問 Person 類實例的 name 屬性,也可以調用 ConsoleLogger 類實例的 log() 方法。
4. 小結
本節介紹了高級類型中的交叉類型,把 &
的意思理解成 and
即可輕松記憶,下一節開始介紹聯合類型。