TypeScript

作者: 大佬教我写程序 | 来源:发表于2021-07-24 20:43 被阅读0次

    TypeScript官网https://www.typescriptlang.org

    js缺陷

    • 没有对类型和参数进行检错、校验的功能,可能会因为一个小小的错误而导致正个程序编译不过去

    TypeScript

    特点
    • 是拥有类型的JavaScript超集,它可以编译成普通、干净、完整的JavaScript代码
    • 强大的工具,用于构建大项目
    • TypeScript提供最新的和不断发展的JavaScript特性
    • TypeScript需要转换成JavaScript才能编译执行

    转换工具

    方法一:

    • 下载
      npm install typescript -g
    C:\Users\gqb>tsc -v
    Version 4.3.5
    
    • 编译成js
      tsc 01first.ts

    方法二:

    • 安装
    npm install ts-node -g
    npm install @types/node -g
    
    • 使用(相当于 编译+运行)
      ts-node 01first.ts

    方法三:

    webpack环境下的ts

    • 下载webpack和webpack-cli
    • webpack init选择配置

    string 和 String

    string: TypeScript中的字符串类型
    String: JavaScript的字符串包装类的类型

    变量名冲突问题

    • 原因:同一目录下两个相同的变量会报错
    • 解决方法:在最后添加一样代码,表示这是独立模块
    export {}
    

    number类型

    输出的是十进制

    let num1: number = 100 
    //二进制
    let num2: number = 0b100
    //八进制
    let num3: number = 0o100
    //十六进制
    let num4: number = 0x100
    

    布尔类型

    let flag: boolean = true
    

    字符串

    var name: string = "why"
    let age: number = 18
    const height: number = 1.88
    

    类型推导/推断(默认赋值):默认情况下会将赋值的数据类型做为前面标识符的类型

    let foo = "foo"
    

    相当于

    let foo:string = "foo"
    

    数组(array)类型

    // 类型注解: type annotation
    const names1: Array<string> = [] // 不推荐(react jsx中是有冲突   <div></div>)
    const names2: string[] = [] // 推荐
    

    对象

    const info = {
      name: "why",
      age: 18
    }
    
    console.log(info.name)
    

    null和undefined

    //只能是null或者undefined
    let n1: null = null
    let n2: undefined = undefined
    

    symbol

    const title1 = Symbol("title")
    const title2 = Symbol('title')
    
    const info = {
      [title1]: "程序员",
      [title2]: "老师"
    }
    

    TS独有类型

    any类型

    // 在不想给某些JavaScript添加具体的数据类型时(原生的JavaScript代码是一样)
    let message: any = "Hello World"
    
    message = 123
    message = true
    message = {
    
    }
    

    unknow类型

    • unknown类型只能赋值给any和unknown类型
    • any类型可以赋值给任意类型

    void类型

    没返回值

    function sum(num1: number, num2: number):void {
      console.log(num1 + num2)
    }
    
    sum(20, 30)
    

    never类型

    确保总是穷尽 了(message: string | number | boolean)的可能类型,防止忘了添加逻辑处理

    function handleMessage(message: string | number | boolean) {
      switch (typeof message) {
        case 'string':
          console.log("string处理方式处理message")
          break
        case 'number':
          console.log("number处理方式处理message")
          break
        case 'boolean':
          console.log("boolean处理方式处理message")
          break
        default:
          const check: never = message
      }
    }
    

    tuple元组类型

    • 元组中每个元素都有自己特性的类型,根据索引值获取到的值可以确定对应的类型
    const info: [string, number, number] = ["gqb", 19, 1.75]
    const name = info[0]
    console.log(name.length)
    

    函数参数及返回值

    // 给参数加上类型注解: num1: number, num2: number
    // 给返回值加上类型注释: (): number
    // 在开发中,通常情况下可以不写返回值的类型(自动推导)
    function sum(num1: number, num2: number) {
      return num1 + num2
    }
    
    sum(123, 321)
    

    匿名函数

    const names = ["abc", "cba", "nba"]
    // item根据上下文的环境推导出来的, 这个时候可以不添加的类型注解
    // 上下文中的函数: 可以不添加类型注解
    names.forEach(function(item) {
      console.log(item.split(""))
    })
    

    对象&&可选类型

    function printPoint(point: {x: number, y: number, z?: number}) {
      console.log(point.x)
      console.log(point.y)
      console.log(point.z)
    }
    
    printPoint({x: 123, y: 321})
    printPoint({x: 123, y: 321, z: 111})
    

    联合类型

    // number|string 联合类型
    function printID(id: number|string|boolean) {
      // 使用联合类型的值时, 需要特别的小心
      // narrow: 缩小
      if (typeof id === 'string') {
        // TypeScript帮助确定id一定是string类型
        console.log(id.toUpperCase())
      } else {
        console.log(id)
      }
    }
    

    类型别名

    • type用于定义类型别名(type alias)
    type IDType = string | number | boolean
    type PointType = {
      x: number
      y: number
      z?: number
    }
    
    function printId(id: IDType) {
    
    }
    
    function printPoint(point: PointType) {
      
    }
    
    

    类型断言 as

    • 转换成更具体的类型
    const el = document.getElementById("why") as HTMLImageElement
    

    非空类型断言 !

    function printMessageLength(message?: string) {
      // if (message) {
      //   console.log(message.length)
      // }
      // vue3源码
      console.log(message!.length)
    }
    

    可选链 ?.

    type Person = {
      name: string
      friend?: {
        name: string
        age?: number,
        girlFriend?: {
          name: string
        }
      }
    }
    
    const info: Person = {
      name: "why",
      friend: {
        name: "kobe",
        girlFriend: {
          name: "lily"
        }
      }
    }
    console.log(info.friend?.girlFriend?.name)
    

    !! 运算符

    const message = "Hello World"
    const flag = !!message
    console.log(flag)//true 
    

    ?? 运算符

    • Hello World 不存在的时候且为null时,就会赋值??后面的值
    let message: string|null = "Hello World"
    
    const content = message ?? "你好啊, 大帅比"
    // const content = message ? message: "你好啊, 大帅比"
    console.log(content)
    

    字面量类型

    • 字面量类型的意义, 就是必须结合联合类型
    type Alignment = 'left' | 'right' | 'center'
    
    let align: Alignment = 'left'
    align = 'right'
    align = 'center'
    
    type Method = 'GET' | 'POST'
    function request(url: string, method: Method) {}
    
    type Request = {
      url: string,
      method: Method
    }
    
    const options:Request = {
      url: "https://www.coderwhy.org/abc",
      method: "POST"
    } 
    
    request(options.url, options.method)
    

    类型缩小

    • typeof 结合 if 语句
    • == === !== switch
      switch (direction) {
        case 'left':
          console.log(direction)
          break;
        case ...
      }
    
    • instanceof 参数实例出处
    class Student {
      studying() {}
    }
    
    class Teacher {
      teaching() {}
    }
    
    function work(p: Student | Teacher) {
      if (p instanceof Student) {
        p.studying()
      } else {
        p.teaching()
      }
    }
    
    • in 用于确定对象是否具有带名称的属性
    type Fish = {
      swimming: () => void
    }
    
    type Dog = {
      running: () => void
    }
    
    function walk(animal: Fish | Dog) {
      if ('swimming' in animal) {
        animal.swimming()
      } else {
        animal.running()
      }
    }
    
    const fish: Fish = {
      swimming() {
        console.log("swimming")
      }
    }
    
    walk(fish)
    

    函数类型

    • 规定传入一个怎样函数,返回值类型
    function calc(n1: number, n2: number, fn: (num1: number, num2: number) => number) {
      return fn(n1, n2)
    }
    
    const result1 = calc(20, 30, function(a1, a2) {
      return a1 + a2
    })
    console.log(result1)
    
    const result2 = calc(20, 30, function(a1, a2) {
      return a1 * a2
    })
    console.log(result2)
    

    参数默认值

    • 如果无值时,参数为undefined时,默认赋值是20,
    // 必传参数 - 有默认值的参数 - 可选参数
    function foo(y: number, x: number = 20) {
      console.log(x, y)
    }
    
    foo(30)
    

    函数的重载,不能使用联合类型解决的话就优先用联合类型

    • 在函数的重载中, 实现函数是不能直接被调用的 add({name: "why"}, {age: 18}) 会报错,只能是重载函数进行间接调用
      image.png

    抽象函数 abstract

    • 抽象类的抽象方法必须被子类实现

    接口

    接口和类的区别
    1、接口类似于类,但接口的成员都没有执行方式,它只是方法、属性、事件和索引的组合而已,并且也只能包含这四种成员;类除了这四种成员之外还可以有别的成员(如字段)。
    2、不能实例化一个接口,接口只包括成员的签名;而类可以实例化(abstract类除外)。
    3、接口没有构造函数,类有构造函数。
    4、接口不能进行运算符的重载,类可以进行运算符重载。
    5、接口的成员没有任何修饰符,其成员总是公共的,而类的成员则可以有修饰符(如:虚拟或者静态)。

    interface CalcFn {
      (n1: number, n2: number): number
    }
    
    function calc(num1: number, num2: number, calcFn: CalcFn) {
      return calcFn(num1, num2)
    }
    
    const add: CalcFn = (num1, num2) => {
      return num1 + num2
    }
    
    calc(20, 30, add)
    

    枚举

    • 定义一些常量,然后在其他地方使用
    enum Direction {
      LEFT = "LEFT",
      RIGHT = "RIGHT",
      TOP = "TOP",
      BOTTOM = "BOTTOM"
    }
    

    泛型

    • 类型的参数化
    // 在定义这个函数时, 我不决定这些参数的类型
    // 而是让调用者以参数的形式告知,我这里的函数参数应该是什么类型
    function sum<Type>(num: Type): Type {
      return num
    }
    
    // 1.调用方式一: 明确的传入类型
    sum<number>(20)
    sum<{name: string}>({name: "why"})
    sum<any[]>(["abc"])
    
    // 2.调用方式二: 类型推到
    sum(50)
    sum("abc")
    

    模块化开发

    模块开发的时候,要需要 declare 声明文件 .d.ts 文件

    • 声明文件
    // 声明模块
    declare module 'lodash' {
      export function join(arr: any[]): void
    }
    
    // 声明变量/函数/类
    declare let whyName: string
    declare let whyAge: number
    declare let whyHeight: number
    
    declare function whyFoo(): void
    
    declare class Person {
      name: string
      age: number
      constructor(name: string, age: number)
    }
    declare module '*.jpg'
    declare module '*.jpeg'
    declare module '*.png'
    declare module '*.svg'
    declare module '*.gif'
    

    相关文章

      网友评论

        本文标题:TypeScript

        本文链接:https://www.haomeiwen.com/subject/zrppmltx.html