美文网首页
Typescript 学习笔记

Typescript 学习笔记

作者: 夹板儿孩 | 来源:发表于2022-11-01 22:51 被阅读0次

    TypeScript 学习笔记

    一、基本数据类型

    基本数据类型与 JavaScript 一致,包含了 number, string, boolean,增加了一个任意值类型 any、unknown、never、void

    • any:任意类型的变量
    • unknown: 表示未知类型
      unknown与any类似 但使用前必须进行断言或守卫
    • never:永不存在的值的类型
    • void: 无任何类型,没有类型
      用于函数时,never表示函数用于执行不到返回值那一步(抛出异常或死循环)的返回值类型,
      即永不存在的值的类型。 而void则表示没有返回值,不返回或返回undefined

    使用原则上

    • 能不用any,就不用any声明时如果不确定具体的类型,则可以使用unknown代替,在使用时用类型断言或类型守卫进行类型收缩
    • never 常用于构造条件类型来组合出更灵活的类型定义
    • void 常用于表示函数没有返回值

    定义变量

    const num: number = 1
    const str: string = 'a'
    

    定义数组

    const num: number[] = [1, 2, 3, 4, 5]
    const str: string[] = ['a', 'b', 'c', 'd', 'e']
    

    联合类型

    let other: number | string = 1
    other = 'a'
    

    二、函数

    函数的定义大致与 JavaScript 一致,仅仅有类型的区分

    普通函数

    function fun(){
      console.log('fun')
    }
    

    有入参的函数

    function fun(num: number, str: string) {
      console.log(num, str)
    }
    

    有返回值的函数

    function fun(): number {
      return 1
    }
    

    函数表达式

    简写方式

    fun 的类型不指定类型,通过 = 赋值决定类型

    const fun = (n1: number, n2: number):number => n1+n2
    console.log(fun(1, 2))
    

    手动指定 fun 的类型

    需要注意 TypeScript 中的 => 与 JavaScript 中的 => 意义不同

    TypeScript 中:(入参名称: 入参类型) => 返回类型

    JavaScript 中: (入参名称) => 函数体

    // 1 简写前变量值为一个函数体
    const fun: (n1: number, n2: number) => number = function(n1: number, n2: number) {return n1+ n2}
    // 2 简写一次后 function 更改为代码段的表达式
    const fun: (n1: number, n2: number) => number = (n1: number, n2: number): number => {return n1 + n2}
    // 3 简写二次后去掉代码段改为一行执行
    const fun: (n1: number, n2: number) => number = (n1: number, n2: number): number => n1 + n2
    

    入参解构函数

    // 解构对象
    function fun({num, str}: {num: number, str: string}) {
      console.log(num, str)
    }
    fun({num: 1, str: 'a'})
    
    // 解构数组
    function fun2([num, str]: [num: number, str: string]) {
      console.log(num, str)
    }
    fun2([1, 'a'])
    

    三、接口(一)

    接口关键字是 interface 。接口的主要作用是对对象的结构进行类型检查,当结构或者类型不匹配时将会报错

    普通接口定义

    错误示例

    interface Person {
      name: string
      age: number
    }
    
    const li_lei: Person = {
      name: '李雷',
      age: 18,
      sex: '男' // Person 接口中没有定义这个属性,则不得擅自增加属性
    }
    
    const han_meimei: Person = { // 当对象中缺失 Person 接口中规定的必传属性, 则会报错
      name: '韩梅梅'
    }
    

    正确示例

    const zhang_san: Person = {
      name: '张三',
      age: 10
    }
    

    可选属性接口定义

    interface Person {
      name: string
      age: number
      sex?: string // 通过 ? 将属性标记为可选属性
    }
    
    const li_lei: Person = {
      name: '李雷',
      age: 18,
      sex: '男'
    }
    
    const han_meimei: Person = {
      name: '韩梅梅',
      age: 18
      // sex: '女' // 可以选择不要这个属性
    }
    

    只读属性接口定义

    定义只读的关键字 readonly

    interface Person {
      readonly id: number
      name: string
    }
    
    const li_lei: Person = {
      id: 1,
      name: '李雷'
    }
    li_lei.id = 3 // [编译报错] 设置了 readonly 的属性被初始化后无法再次修改
    

    任意属性接口定义

    interface Person {
      name: string
      age: number
      sex?: string
      [propName: string]: unknown
    }
    
    const li_lei: Person = {
      name: '李雷',
      age: 18,
      sex: '男', // Person 接口中没有定义这个属性,则不得擅自增加属性
      like: '开车',
      birthday: '2000-01-01'
    }
    
    const han_meimei: Person = { // 当对象中缺失 Person 接口中规定的必传属性, 则会报错
      name: '韩梅梅',
      age: 18,
      like: '购物',
      birthday: '2000-01-01'
    }
    

    接口函数字段定义

    interface Person {
      readonly id: number
      name: string,
        
      eat(food: string): void // 第一种函数定义方式
        
      drink: (food: string) => void // 第二种函数定义方式 [TypeScript 中:(入参名称: 入参类型) => 返回类型]
    }
    

    四、类

    类的关键字是 class 作为对象的模板被引入,class 的本质是一个 function

    类的定义

    类的定义分为匿名类和命名类,在定义类时需要注意,类不能同名

    // 匿名类
    let clazz = class {}
    // 命名类
    class Clazz{}
    

    构造器与属性定义

    constructor: 构造器,类在被 new 的时候将会被调用。不写时默认是无参构造。一个 class 只能有一个 constructor

    注意,当 constructor 被定义为 private 属性后,class 将无法被 new

    public: 共有属性,属性被 new 以后可以通过 .(点) 的方式进行访问

    private: 私有属性,属性仅仅在 class 内部可以进行访问,外部无法访问

    let clazz = class {
      public msg: string
      private num: number
      // 构造函数
      constructor(msg: string) {
        this.msg= msg
      }
    }
    class Clazz{
      public msg: string
      private num: number
      // 构造函数
      constructor(msg: string) {
        this.msg = msg
      }
    }
    console.log(new clazz('abc').msg)
    console.log(new Clazz('abc').msg)
    // console.log(new clazz('abc').num) // 无法访问
    // console.log(new Clazz('abc').num) // 无法访问
    

    get & set

    class Person {
      private age: number
      constructor(age: number) {
        this.age = age
      }
      getAge(){
        console.log('getAge')
        return this.age
      }
      setAge(num: number) {
        this.age = num
        console.log('setAge: ' + num)
      }
    }
    const person = new Person(18)
    console.log(person.getAge())
    person.setAge(19)
    console.log(person.getAge())
    

    继承

    1. 继承使用关键字 extends

    2. 子类中访问父类使用 super 关键字

    3. 实例化子类时会优先实例父类,super() 必须在 constructor 的第一行位置

    class Clazz{
      public msg: string
      constructor(msg: string) {
        this.msg = msg
      }
    }
    class Student extends Clazz {
      constructor() {
        super('父')
        console.log(super.msg) // undefined
      }
      say(): void {
        console.log(super.msg) // undefined
        console.log(this.msg) // 父
      }
    }
    new Student().say()
    

    五、接口(二)

    接口定义

    interface Person {
      readonly id: number
      name: string,
        
      eat(food: string): void
        
      drink: (food: string) => void
    }
    

    实现一

    const li_lei: Person = {
      id: 1,
      name: '李雷',
      eat: (food: string) => console.log(li_lei.name + ' 吃 ' + food),
      drink: (food: string) => console.log(li_lei.name + ' 喝 ' + food)
    }
    
    li_lei.eat('包子')
    li_lei.eat('西瓜汁')
    

    实现二

    class han_meimei implements Person{
      id = 2
      name = '韩梅梅'
      eat = (food: string) => console.log(this.name + ' 吃 ' + food)
      drink(food: string) {
        console.log(this.name + ' 喝 ' + food)
      }
    }
    
    const hmm: han_meimei = new han_meimei()
    hmm.eat('包子')
    hmm.drink('西瓜汁')
    

    六、断言 (as)

    断言的作用在于当函数中出现了多种类型时,但是又必须使用某一种类型。如果不使用断言,在编译过程中会无法编译

    断言更像是告诉编译器:你不需要管我,我自己知道我在干什么

    但是断言虽然编译通过了,但是容易在运行中出现异常。所以在使用过程中需要更加的谨慎

    注意,断言不是类型转换。

    示例

    断言先就这样吧,稍微理解一下,先学点别的

    interface ApiError extends Error{
      code: number
    }
    interface HttpError extends Error{
      statusCode: number
    }
    
    // function isApiError(error: Error) {
    //   return typeof error.code !== 'undefined'; // 没有使用断言,编译器无法编译 code 编译会报错
    // }
    function isApiError(error: Error) {
      return typeof (error as ApiError).code !== 'undefined'; // 将 error 断言为 ApiError,才可以访问到 code 属性
    }
    
    function isHttpError(error: Error) {
      return typeof (error as HttpError).statusCode !== 'undefined';
    }
    
    
    const apiError: ApiError = {
      code: 1,
      name: 'apiError',
      message: ''
    }
    const httpError: HttpError = {
      statusCode: 200,
      name: 'httpError', 
      message: ''
    }
    
    
    console.log(isApiError(apiError))   // true
    console.log(isHttpError(apiError))  // false
    console.log(isApiError(httpError))  // false
    console.log(isHttpError(httpError)) // true
    

    七、元组

    元祖可以理解为更高一级的数组,元组的数据只能是规定的联合类型

    示例

    const arr: [string, number] = [] // 元类型 [string, number]
    arr.push('a')
    arr.push(1)
    arr.push('b')
    arr.push(2)
    
    arr.push(true) // boolean 不在元类型中,将会报错
    

    八、枚举

    枚举要求值必须是唯一的

    枚举的定义

    enum Week {
      Mon, Tue, Wed, Thu, Fri, Sat, Sum
    }
    // 枚举默认从 0 开始例如
    console.log(Week.Mon === 0) // true
    console.log(Week[0] === 'Mon') // true
    

    手动指定枚举的值

    enum Week {
      Mon = '一',
      Tue = '二',
      Wed = '三',
      Thu = '四',
      Fri = '五',
      Sat = '六',
      Sum = '天'
    }
    console.log(Week.Sum) // 天
    

    相关文章

      网友评论

          本文标题:Typescript 学习笔记

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