1. 程式人生 > 其它 >typeScript學習(二)

typeScript學習(二)

聯合型別和型別保護 聯合型別 |
// 聯合型別和型別保護
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 extends
Item> { 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)