TS

147 阅读3分钟

一. 什么是TS ?

TS是JS的超集,在原有的语法基础上,添加类型并切换为基于类的面向对象语言

面向项目:

TS:面向解决大型的复杂项目、架构、代码维护复杂场景

JS:脚本化语言,用于面向简单项目场景

二. TS的基础类型和语法。

  let isShow: boolean = false;
  let name: string = 'liangzai'
  let num: number = 2
  let n: null = null
  let u: undefined = undefined
  
  let arr: Array<string> = ['baidu', 'juejin']
  let arr: string[] = ['baidu', 'juejin']
  
  元组 - tuple
  let tupleArray: [string, boolean] = ['baidu', false]
  
  枚举 - enum
  数字型枚举
  enum Score {
      BAD, // 0
      NG, // 1
      GOOD, // 2
      PERFECT // 3
  } 默认从0开始
  let score: Score = Score.GOOD // 2
  
  字符串类型枚举
  enum Score1 {
      BAD = 'BAD'
      NG = 'NG'
      GOOD = 'GOOD'
      PERFECT = 'PERFECT'
  }
  
  反向映射
  let scoreName = Score1[0] // BAD
  let scoreValue = Score['BAD'] // 0
  
  异构类型
  enum Enum {
      A, // 0
      B, // 1
      C = 'C',
      D = 'D',
      E = 8,
      F // 9
  } 数字型枚举是根据上一个的值递增的,所以当 E = 8时,F就 等于9any unkonwn void
  any : 绕过所有类型检查,类型检查和编译筛查取消
  let anyValue: any = 123
  anyValue = 'anyValue'
  anyValue = false
  let value1: boolean = anyValue
  
  unknown: 绕过所有类型检查,但是可以禁止更改传递。
  let unknownValue: unkonwn = 123
  unknownValue = 'anyValue'
  unknownValue = false
  let value1: unkonwn = unknownValue // ok
  let value2: any = unknownValue // ok
  let value3: boolean = unknownValue // no ok
  
  void: 声明返回为空,通常用在函数
  function voidFunction(): void {
      console.log('没有返回值')
  }
  
  never: 永不能执行完 或者永远error
  function errorGen (msg: string): never {
      throw new Error(msg)
  }
  function infiniteLoop(): never {
      white(true) {
          // 业务逻辑
      }
  }
  
  对象
  Object / object / {}
  
  
  接口  interface
  对行为模块的抽象,具体的行为是有类来实现
  interface Person {
      name: string;
      age: number;
  }
  let person: Person = {
      name: 'juejin',
      age: 100
  }
  // 只读
  interface Person1 {
      readonly name: string;
      age: number;
  }
  let arr: number[] = [1,2,3,4]
  let ro: ReadonlyArray<number> = arr
  ro[0] = 12 // 赋值 - error
  ro.push(5) // 增加 - error
  ro.length = 10 // 长度改变 - error
  arr =ro // 覆盖 - error
  
  // 任意可添加属性
  interface Person2 {
      name: string;
      age: number;
      [propName: string]: any // 用这种方式来拓展接口可描述程度
  }
  const c1 = { name: 'js'}
  const c2 = { name: 'js', age: 2}
  const c3 = { name: 'ts', level: 2}
  
   交叉类型
   interface A {
       inner: D
   }
   interface B {
       inner: E
   }
   interface C {
       inner: F
   }
   interface D {
       d: boolean
   }
   interface E {
       e: string
   }
   interface F {
       f: number
   }
  type ABC = A & B & C;
  
  let abc: ABC = {
      inner: {
          d: false,
          e: 'juejin',
          f: 100
      }
  }
  
  // 注意合并的冲突
  interface A {
      c: string;
      d: string;
  }
  interface B {
      c: number;
      e: string;
  }
  let AB = A & B;
  let ab: AB; 因为合并的关系是 ‘且’。这样就会导致 C 变成永远never!!!
  
  断言  类型的声明和转换 (就是我们和编译器之间的告知和交流)
  尖括号形式
  let anyValue: any = 'hello'
  let anyLength: number = (<string>anyValue).length // 虽然之前是any类型,但是当他到了这里的时候,可以保证他是个字符串。
  // as 声明形式
  let anyValue: any = 'hello'
  let anyLength: number = (anyValue as string).length
  
  // 非空判断 - 只确定不是空
  type time = () => number;
  const start = (Time: time | undefined) {
      // 业务逻辑
      if(xxxx) {
          let time1 = time!() // 具体类型待定,但是非空确认
      }
  }
  
  看题: 
      const ts: number | undefined = undefined;
      const juejin : number = ts!;
      console.log(juejin)
      // 以上会转义为
      const ts = undefined;
      const juejin = ts!; 
      console.log(juejin) // undefined .所以尽量在逻辑里面做断言,不要再声明的就去做断言。
   
   类型守卫 - 预发规范内额外的确认
   interface men {
       name: string;
       time: number;
   }
   interface women {
       name: string;
       color: boolean;
   }
   let person = men | women ;
   function in (param: person) { // 用 ‘in’的方式做属性守卫
       if('time' in param) {
           console.log('time' + param.time)
       }
       if('color' in param) {
           console.log('color' + param.color)
       }
   }
   使用 typeOf 和 instanceof - 类型分场景下的身份确认
   function type (name: string, param: boolean | number) {
       if (typeOf param === 'number') {
           return 'men' + name + ':' + param
       }
       if (typeOf param === 'boolean') {
           return 'women' + name + ':' + param
       }
   }
   const getPerson = (param: person) => {
       if(param instanceof men) {
           return param.time
       }
       if(param instanceof women) {
           return param.color
       }
   }
   以上就是 通过这三种方式来判断类型守卫的方式
   // 自定义的方式来判断
   const isMen = function (param: men | women): param in men {
       return 'time' in param
   }
   const getType = (param: men | women) => {
       if (isMen(param)) {
           return param.time
       }
   }
   
   泛型 - 复用
   让模块可以支持多种类型数据 - 让类型和值一样,可以被赋值和传递
   function fanxing <T, U>(name: T, age: U): T {
       return name + age
   }
   console.log(fanxing<string, number>('xiaoming', 100))
   
   装饰器  
   function Juejin (target: Function): void {
       target.prototype.get = function(): void{
           
       }
   }
   
   function propsWrapper (target: Object, key: string) {
       // 属性的统一操作
       Object.definPproperty(target, key, {
           get(){}
           set(){}
       })
   }
   @Juejin   // 类装饰器
   class Js {
       constructor () {
           
       }
       @propsWrapper // 属性装饰器
       public name: string
       
       // 方法装饰器
   }