TypeScript-9.高級類型1

筆記。

  • 交叉類型
  • 聯合類型
  • 類型保護
  • null和undefined
  • 類型保護和類型斷言
  • 類型別名
  • 字面量類型
  • 枚舉成員類型
  • 可辨識聯合
    // 交叉類型 &
    const mergeFunc = <T, U>(arg1: T, arg2: U): T & U => { // 返回值類型是多種
      let res = {} as T & U
      res = Object.assign(arg1, arg2)
      return res
    }
    console.log(mergeFunc({ a: 'a', b: 'b'}, { b: '1', c: 'c'})) // {a: 'a', b: '1', c: 'c'}
    
    // 聯合類型 type1 | type2 | type3
    const getLengthFunc = (content: string | number): number => {
      if (typeof content === 'string') { return content.length }
      else { return content.toString().length }
    }
    console.log(getLengthFunc('abcd')) // 4
    console.log(getLengthFunc(22312)) // 5
    
    // 類型保護
    const valueList = [123, 'abc']
    const getRandomValue = () => {
      const num = Math.random() * 10
      if (num < 5) { return valueList[0] }
      else { return valueList[1] }
    }
    const item = getRandomValue() // 隨機的值 不知道哪種類型
    // 1.自定義類型保護(一般用於複雜的判斷,這種簡單的建議用下面幾種)
    function isString(value: number | string): value is string {
      return typeof value === 'string'
    }
    // if (item.length) { console.log(item.length) } 因類型不確定報錯
    // else { console.log(tiem.toFixed(2)) }
    if (isString(item)) { console.log(item.length) }
    else { console.log(item.toFixed(2)) }
    
    // 2.typeof 類型保護  string/number/boolean/symbol 四種之一
    if (typeof item === 'string') { console.log(item.length) }
    else { console.log(item.toFixed(2)) }
    
    // 3.instanceof 類型保護
    class CreateByClass1 {
      public age = 18
    }
    class CreateByClass2 {
      public name = 'van'
    }
    function getRandomItem() {
      return Math.random() < 0.5 ? new CreateByClass1() : new CreateByClass2()
    }
    const item1 = getRandomItem()
    if (item1 instanceof CreateByClass1) { console.log(item1.age) }
    else { console.log(item1.name) }
    
    // null和undefined 任何類型的子類型
    let values = '123'
    // values = undefined // 配置文件 strictNullChecks
    // string | undefined / string | null / string | undefined | null 三者不同
    const sumFunc = (x: number, y?: number) => {
      return x + (y || 0)
    }
    
    // 類型保護和類型斷言 !
    const getLengthFunction = (value: string | null): number => {
      // if (value == null) { return 0 }
      // else { return value.length } 簡寫如下
      return (value || '').length
    }
    
    function getSpliceStr(num: number | null): string {
      function getRes(prefix: string) {
        return prefix + num!.toFixed().toString()
      }
      num = num || 0.1
      return getRes('van-')
    }
    console.log(getSpliceStr(1.782))
    
    // 類型別名 type
    type TypeString = string
    let str2: TypeString
    type PositionType<T> = { x: T, y: T }
    const position1: PositionType<number> = {
      x: 1,
      y: -1
    }
    const position2: PositionType<string> = {
      x: '3.22215',
      y: '1.23421'
    }
    type Childs<T> = {
      current: T,
      child?: Childs<T>
    }
    let ccc: Childs<string> = {
      current: 'first',
      child: {
        current: 'second',
        child: {
          current: 'third'
        }
      }
    }
    type Alias = {
      num: number
    }
    interface Inter { // implements 擴展的時候用interface
      num: number
    }
    let _alias: Alias = {
      num: 123
    }
    let _interface: Inter = {
      num: 321
    }
    _alias = _interface // 類型別名和接口 兼容
    
    // 字面量類型
    // 1. 字符串字面量(具體的string)
    type Name = 'van'
    // const name1: Name = 'v' 報錯
    type Direction = 'north' | 'west' | 'south' | 'east'
    function getDirectionFirstLetter(direction: Direction) {
      return direction.substr(0, 1)
    }
    console.log(getDirectionFirstLetter('east'))
    // 2. 數字字面量(具體的number)
    type Age = 18
    interface InfoInterface {
      name: string
      age: Age
    }
    const _info: InfoInterface = {
      name: 'van',
      age: 18
      // age: 3 // 必須是18 不然報錯
    }
    
    // 枚舉成員類型
    
    // 可辨識聯合
    // 兩要素:1.具有普通的單例類型屬性 2.一個類型別名包含了哪些類型的聯合
    interface Square {
      kind: 'square'
      size: number
    }
    interface Rectangle {
      kind: 'tangle'
      height: number
      width: number
    }
    interface Circle {
      kind: 'circle'
      radius: number
    }
    type Shape = Square | Rectangle | Circle // 聯合類型
    function assertNever(value: never): never {
      throw new Error('Unexpected object: '+ value)
    }
    function getArea(s: Shape): number {
      switch(s.kind) {
        case 'square': return s.size * s.size;
        break;
        case 'tangle': return s.height * s.width;
        break;
        case 'circle': return Math.PI * s.radius ** 2;
        break;
        default: return assertNever(s);
      }
    }
    // 完整性檢查
    // 1. 配置文件 strictNullChecks: true
    // 2. 使用never類型
    

    學得慢 不重要。書看的慢 不重要。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章