今天要來介紹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
來做確認。
今天的學習筆記就到這邊,謝謝閱讀。:)