今天要來介紹Intersection、Type guard。
Intersection 型別是把兩種定義好的 type 做合併,這在定義物件的時候滿方便的:
type Admin = {
name: string
id: number
}
type Reader = {
name: string
visitedDate: Date
}
type libraryMember = Admin & Reader
const libraryInTc: libraryMember = {
name: 'Claire',
id: 0,
visitedDate: new Date()
}
上面可以看到 type libraryMember 結合了 Admin 和 Reader 這兩種 type,如果要定義 libraryMember 的物件就一定要有 name、id、visitedDate 這三種屬性。這個跟 interface 的概念有點像,上面的 type 可以改成 interface,然後用繼承的方式做 intersecition 型別:
interface Admin {
name: string
id: number
}
interface Reader {
name: string
visitedDate: Date
}
interface libraryMember extends Admin, Reader {}
Type Guards 通常是使用 Union 型別的時候會派上用場,Union 型別因為為變數定義了兩種以上不同的型別,所以在變數使用上需要更精確的規範,以下有幾種方式可以再更加確認接收到 Union 型別的變數的詳細型別:
typeof 確認該變數是哪一種型別type Combinable = string | number
function add(a: Combinable, b: Combinable) {
if (typeof a === 'string' || typeof b === 'string') {
return a.toString() + b.toString()
}
return a + b
}
上面可以看到當確認 a 或 b 不是字串之後,下面 return 的 a + b 會是數字。
當不能用 typeof 確認型別時,比如說是要比對兩個物件內的屬性時,可以用 JavaScript 原本就有的 in 運算子,這邊把上面的 libraryMember 改成 Union 型別,並且試著印出定義成 libraryMember 的物件內的 id 屬性
可以看到 libraryInTw.id 被報錯,因為 TypeScript 不確定傳進 printAll 裡面的到底是 Admin 還是 Reader,這時就可以使用 in 來做二次確認
第三種是 instanceof,這也是 JavaScript 原本就有的,主要是去確認傳進去的參數有沒有繼承到 prototype chain 上面的方法,當一個變數被指定為 Union 型別且定義的是兩個 classes,就可以使用 instanceof 來做確認。
今天的學習筆記就到這邊,謝謝閱讀。:)