TypeScript的安装和使用

TypeScript的安装和使用

安装

npm i typescript
yarn add typescript

运行

首先安装ts-node
npm i ts-node
yarn add ts-node

运行ts文件:ts-node XXX.ts 类比node运行js文件

基础类型

//1. boolean
let trueOrFalse:boolean = true

//2. number
let num1:number  = 1

//3. string
let str1:string = "字符串类型"

//4. undefined 和 null
let u:undefined = undefined
let n:null = null
//默认情况下 null和undefined为所有类型的子类型,可以进行赋值

//5. any  不清楚什么类型,不做过多叙述,非必要不推荐使用

//6. unknown  u代表任何类型,它的定义和 any 定义很像,但是它是一个安全类型,使用 unknown 做任何事情都是不合法的。

//7. void  表示没有任何类型

//8. never 表示那些用不存在的值

//9. 数组
let list:number[] = [1,2,3] //内部元素必须是数字,不是则会报错
let list2:Array<number> = [1,2,3]

//10. 元组
let tuple:[number,string] = [18,"阿巴阿巴"]
//可以使用push方法推入相同的类型 
tuple.push(123) //不是则会报错
tuple.push(true) //会报错

//11. 函数
function add(num1:number,num2:number):number{
    return num1+num2
}
//箭头函数写法
const addFn=(num1:number,num2:number):number=>{
    return num1+num2
}

interface

  • TS设计出来用于定义对象类型的,可以对对象的形状进行描述
  • interface Person {
      name:string,
      age:number
    }
    // 一定要一一对应,类型对应,否则会发生报错
    const p1:Person = {
      name:"卢本伟!"
      age:19
    }
    
  • 属性可选 ?标识
    interface Person{
      name:string,
      age?:number
    }
    //不写age也不会报错
    const p1:Person = {
      name:"我靠"
    }
    
  • 只读属性,不希望属性更改 readonly
    interface Person{
      readonly id:number
      name:string
      age:number
    }
    const p1:Person = {
      id:1
      name:"string",
      age:18
    }
    p1.id = 2 //报错
    
  • interface描述函数类型
    interface IAdd{
      (x:number,y):number
    }
    
    const add:IAdd = (num1,num2) => {
      return num1 + num2
    }
    

枚举

  • 基本使用
    enum Direction {
      up,
      down,
      left,
      right
    }
    //特点:数字递增 枚举成员会被赋值为从0开始递增的数字
    Direction.up //0
    Direction.down //1
    Direction.left //2
    Direction.right //3
    
    // 枚举会对枚举名反向映射
    Direction[0] //up
    Direction[1] //down
    Direction[2] //left
    Direction[3] //right
    
    //如果枚举第一个元素赋有初始值,那么会从初始值进行递增
    
  • 反向映射的原理
    const Direction
    (function(Direction){
      Direction[Direction("up")=0] = "up"
      Direction[Direction("down")=1] = "down"
      Direction[Direction("left")=2] = "left"
      Direction[Direction("right")=3] = "right"
    })(Direction||(Direction = {}))
    
    //主体代码被包含在一个自执行函数里,封装自己独特的作用域
    //执行如下代码
    Direction[Direction("up")=0] = "up"
    //相当于
    Direction["Up"] = 0
    Direction[0] = "Up"
    

高级类型

  • 联合类型

    let mix:number|string
    num = 123
    num = "abc"
    
    //只能访问公用方法,如果不是共用方法那么则会报错
    
  • 交叉类型

    interface Person{
      name:string
      age:number
    }
     //这种写法让Teacher继承了Person的属性,type则是类型别名的表示
    type Teacher = Person & {project:string}
    

    联合类型是取几种类型中的任意一种,而交叉类型则是把几种类型合并起来

  • 类型断言

     function getLength(text:string|number):number{
      const str = text as string //强制规定str是字符串类型
      if(str.length){
        return str.length
      }else{
        const number = text as number
        return number.toString().length
      }
     }
    
  • 泛型(对类型进行编程)

    • 我们先简单举个例子
     //这是我们JS定义的函数,并没有进行类型约束
     function id(arg){
      return arg
     }
    
     //我们来给他加上类型  规定输入类型和输出类型同为Number类型
     function id(arg:number):number{
      return arg
     }
    
     //这种方式的缺点相当明显,就是只能处理Number类型,无法拓展和通用
     //有人可能说可以用any来替代,但是这同时也让类型失去原有的意义,不在进行类型保护
    
    • 改进方法:T作为占位符填充类型
    //这种就是所说的泛型,可以将<T>规定的类型链式传递给参数类型和返回类型
     function id<T>(arg:T):T{
      return arg
     }
    
    id<number>(123) //number将向下传递
    id<string>("怎么说呢") //同理
    
    /**
     * T代表Type ,定义泛型时通常用作第一个类型变量名称,除了T之外,还有如下
     * 1. K(Key):表示对象中的键类型
     * 2. V(Value):表示对象中的值类型
     * 3. E(Element):表示元素类型
    */
    
    //定义多个类型变量
    function identity<T,U>(value:T,message:U):T{
      console.log(message)
      return value
    }
    
    • 泛型接口
    interface Identities<V, M> {
        value: V,
        message: M
    }
    
    function identity<T, U>(value: T, message: U): Identities<T, U> {
        console.log(typeof (value)) //number
        console.log(typeof (message)) //string
        let identities: Identities<T, U> = {
            value,
            message
        }
        return identities
    }
    
    console.log(identity(123,"HASHI"))
    
    • 泛型约束
      • 确保属性是存在的
        interface Length{
          length:number
        }
       
        function id<T extends Length>(arg:T):T{
          console.log(arg.length) //通过继承的方式确保属性存在
          return arg
        }
        
        //还可以通过 “,” 分隔多种约束类型 例
        <T extends Length,Type2,Type3>
      
      • 检查对象上的键是否存在
        interface Person{
          name:string,
          age:number,
          sex:string
        }
        type K1 = keyof Person; // "name" | "age" | "location"
        type K2 = keyof Person[];  // number | "length" | "push" | "concat" | ...
        type K3 = keyof { [x: string]: Person };  // string | number
          
        // 通过K extends keyof T 确保参数key一定是对象中含有的键
        function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
          return obj[key];
        }
        
        let tsInfo = {
           name: "Typescript",
           supersetOf: "Javascript",
           difficulty: Difficulty.Intermediate
        }
         
        let difficulty: Difficulty = 
          getProperty(tsInfo, 'difficulty'); // OK
      
        let supersetOf: string = 
          getProperty(tsInfo, 'superset_of'); // Error
      
      • 泛型条件类型
        T extends U ? X : Y
      
  • 常用泛型工具

    1. Partial 将某个类型里的属性全部变为可选项?
         //定义方法
         type Partial<T> = {
          //keyof T 拿到所有属性名 ,通过in进行遍历 再将值赋值给P,通过T[P]获取相应的属性值,?则是将所有属性变成可选
          [P in keyof T]?:T[P]
         }
      
          interface Person {
              name: string,
              age: number,
              sex: string
          }
          //并不会报错
          const p1: Partial<Person> = {
              name: "123"
          } 
      
    2. Record 将K中所有的属性的值转化为T类型
      //定义方法
      type Record<K extends keyof any,T> = {
       [P in K]:T
      }
      
      interface PageInfo{
       title:string
      }
      
      type Page = "home" |"about" |"contact"
      
      const x:Record<Page,PageInfo> = {
         about:{title:"about"},
         contact:{title:"contact"},
         home:{title:"home"}
      }
      
    3. Pick 将某种类型中的子属性挑出来,变成包含这个类型部分属性的子类型
        //定义方法
        type Pick<T,K extends keyof T>={
               [P in K]:T[P]
        }
      
        interface Todo{
          title:string,
          age:number,
          isFinished:boolean
        }
      
        type TodoPreview = Pick<Todo,"title"|"isFinished"
      
        const x:TodoPreview = {
         title:"阿哲",
         isFinished:false
        }
      
    4. Exclude 将某个类型中属于另一个的类型移除掉
       //定义方法
      type Exclude<T,U>= T extends U ? never:T
      
      type T0 = Exclude<"a" | "b" | "c", "a">; // "b" | "c"
      type T1 = Exclude<"a" | "b" | "c", "a" | "b">; // "c"
      type T2 = Exclude<string | number | (() => void), Function>; // string | number
      
    5. ReturnType 获取函数T的返回类型
       type ReturnType<T extends(...args:any)=>any> = T extends (...args:any) = >infer R? R;any
       
      type T0 = ReturnType<() => string>; // string
      type T1 = ReturnType<(s: string) => void>; // void
      type T2 = ReturnType<<T>() => T>; // {}
      type T3 = ReturnType<<T extends U, U extends number[]>() => T>; // number[]
      type T4 = ReturnType<any>; // any
      type T5 = ReturnType<never>; // any
      type T6 = ReturnType<string>; // Error
      type T7 = ReturnType<Function>; // Error
      
posted @ 2022-06-21 14:01  春天游泳。  阅读(174)  评论(0编辑  收藏  举报