typeScript學習(二)
阿新 • • 發佈:2021-12-09
聯合型別和型別保護
聯合型別 |
// 聯合型別和型別保護 interface Bird { fly: boolean sing: () => {} } interface Dog { fly: boolean bark: () => {} } //聯合型別 function trainAnial(animal: Bird | Dog) { // 使用聯合型別的話ts不知道你的animal是哪個interface,所以會報錯 animal.sing() } //型別保護 //這個時候就要用到型別斷言,比如下面的(型別斷言as的方式進行型別保護) function trainAnial(animal: Bird | Dog) { if (animal.fly) { ;(animal as Bird).sing() } ;(animal as Dog).bark() } // 型別保護第二種方法(in 語法來做型別保護) function trainAnialSecond(animal: Bird | Dog) { if ('sing' in animal) { animal.sing() } else { animal.bark() } } // 型別保護第三種方法(typeof語法做型別保護) function add(first: string | number, second: string | number) { if (typeof first === 'string' || typeof second === 'string') { return `${first}${second}` } return first + second } // 型別保護第四種方法(instanceof語法做型別保護)(只能用於class,不能用class) class NumberObj { count: number = 0 } function addSecond(first: object | NumberObj, second: object | NumberObj) { if (first instanceof NumberObj && second instanceof NumberObj) { return first.count + second.count } return 0 }
列舉型別(可正查反查)
//列舉(可正查反查) enum Status { OFFline, online, deleted, } console.log(Status) console.log(Status[0]) //OFFline console.log(Status.OFFline) //0 // { // '0': 'OFFline', // '1': 'online', // '2': 'deleted', // OFFline: 0, // online: 1, // deleted: 2 // } enum Status1 { OFFline = 1, online, deleted, } console.log(Status1) // { // '1': 'OFFline', // '2': 'online', // '3': 'deleted', // OFFline: 1, // online: 2, // deleted: 3 // }
泛型 generic 泛指的型別
// 泛型 generic 泛指的型別 function join<T, P>(first: T, second: P): T { return first } join<string, string>('1', '2') function map<ABC>(params: Array<ABC>) { return params } map<string>(['123'])
類中的泛型以及泛型型別
//類中的泛型 interface Item { name: string } // T繼承了Item,表示T裡面一定要有Item的所有屬性 class DataManager<T extendsItem> { constructor(private data: T[]) {} getItem(index: number): string { return this.data[index].name } } const data = new DataManager([{ name: '11' }]) // 泛型約束(用extends 聯合型別或interface) class DataManager2<T extends number | string> { constructor(private data: T[]) {} getItem(index: number): T { return this.data[index] } } interface Test { name: string } const data = new DataManager2<number>([]) console.log(data.getItem(0)) // 如何使用泛型作為一個具體的型別註解 function hello<T>(param: T) { return param } const func: <T>(param: T) => T = hello
namespace 名稱空間(類似與模組化,閉包,外部訪問不到裡面的變數,只有export部分變數才可以被外部訪問到)
//namespace 形成閉包,只把Home暴露出去,其他三個方法訪問不了 namespace Home { class Header { constructor() { const elem = document.createElement('div'); elem.innerText = 'This is Header'; document.body.appendChild(elem); } } class Content { constructor() { const elem = document.createElement('div'); elem.innerText = 'This is Content'; document.body.appendChild(elem); } } class Footer { constructor() { const elem = document.createElement('div'); elem.innerText = 'This is Footer'; document.body.appendChild(elem); } } //namespace export(只匯出Page,可以通過 new Home.Page訪問得到) export class Page { constructor() { new Header(); new Content(); new Footer(); } } }
全域性型別(自己定義一個.d.ts檔案)
也可以寫成下面這種interface的語法,實現函式過載
上面是對變數和函式進行型別定義,下面是對物件進行型別定義
模組程式碼的型別描述檔案(es6模組化d.ts,最後記得export匯出)
泛型中keyof語法的使用
interface Person {
name: string
age: number
gender: string
}
//幫助理解
// type NAME = 'name';
// key: 'name';
// Person['name'];
// type T = 'age'
// key: 'age'
// Person['age']
// type T = 'gender'
// key: 'gender'
// Person['gender']
// 用泛型結合keyof的方式解決key值不準確的問題
// 1、keyof是遍歷迴圈Person的key
// 2、例如 T extends name => 恆等於 type T = name 所以 引數key:name
class Teacher {
constructor(private info: Person) {}
getInfo<T extends keyof Person>(key: T): Person[T] {
return this.info[key]
}
}
const teacher = new Teacher({
name: 'zhen',
age: 28,
gender: 'male',
})
const test = teacher.getInfo('age')
console.log(test)