• 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)
    

      

  • 相关阅读:
    好吧,又是两分钟看完一道投机取巧的算法题
    这道算法题太太太太太简单啦
    三分钟看完两道套数学公式的算法题
    三分钟看完「分糖果」算法问题
    LeetCode 第 26 号问题:删除排序数组中的重复项
    如何使用「番茄法」高效的写算法题?
    LeetCode 第 94 号问题:二叉树的中序遍历
    小知识:什么是「欧几里得算法」
    LeetCode 第 101 号问题:对称二叉树
    LeetCode 第 20 号问题:有效的括号
  • 原文地址:https://www.cnblogs.com/gengzhen/p/15652338.html
Copyright © 2020-2023  润新知