初识TS(TS的基础知识)

  • 用前准备

    • 全局安装ts包

      • npm install -g typescript

    • 自动编译

      • npm create vite@latest ts-pro -- --template vanilla-ts

        • npm create vite@latest   使用最新版本的vite创建项目

        • ts-pro   项目名称

        • -- --template vanilla-ts     创建项目使用的模板为原生ts模板

  • 类型注释

    • let msg: string

      • msg 只能被赋值 string 字符串

    • 常见类型:

      • 简单

        • number,string,Boolean,null,undefined

      • 复杂

        • 数组,函数

        • TS新增类型

          • 联合类型,类型别名,接口(interface),字面量类型,泛型,枚举,void,any等

    • 如何进行类型注释

      • 简单类型

        • let age: number = 18

      • 数组类型

        • 限制变量类型伪数组,并且可以限制数组成员类型

          • let arr = []

        • 编码时提示数组属性和方法并且也可以提示成员的属性和方法

        • 注解语法

          • let arr: number[] = [1,2,3] (推荐)

          • let arr2: Array<number> = [1,2,3] (泛型写法)

      • 联合类型和别名类型

        • 联合类型

          • 将多个类型合并成一个类型对变量进行注解

            • let arr3: (string | number)[] = [18,'jack'] (表明数组arr3的成员既可以是string类型也可以是number类型)

        • 类型别名

          • 通过type关键词给写起来比较复杂的类型起一个其它的名字,用来简化和复用(命名一般用大驼峰格式) -

              type ItemType = (string | number)[]
              
              let arr3: ItemType = ['jack',100]
              let arr4: ItemType = ['john',200]
  • 函数类型

    • 函数类型是给函数添加类型注解,本质上就是给函数的参数和返回值添加类型约束

    • 基础使用 -

        function add(a: number,b:number): number {
          return a + b
        }
        // 函数参数注解类型之后补单限制了参数的类型还限制了参数为必填
        // 函数返回值注解类型之后限制了该函数内部return出去的值必须满足类型要求
    • 函数表达式

      • 函数表达式的类型注解有两种方式,参数和返回值分开注解和函数整体注解

      • 参数和返回值分开注解 -

          const add1 = (a:number,b:number):number => {
            return a + b
          }
      • 函数整体注解(只针对于函数表达式) -

          type AddFn = (a:number,b:number) => number
          
          const add1:AddFn = (a,b) => {
            return a + b
          }
    • 可选参数

      • 可选参数表示当前参数可传可不传,一石传递实参必须保证参数类型正确 -

          function buildName(firstName: string, lastName?: string) {
            if (lastName) {
                return `${firstName}$[lastName}`
              } else {
                return firstName
              }
          }
          
          console.log(buildName('foo'))
          console.log(buildName('foo','oof'))
          
          lastName参数表示可选参数,可传可不传,一旦传递实参必须保证类型为string类型
    • 无返回值-void

      • js中的有些函数只有功能没有返回值,此时使用void进行会绘制注释,明确表示函数没有函数值 -

        function eachArr(arr: number[]): void {
            arr.forEach((item) => {
                console.log(item)
            })
        }
        ​
        在js中如果没有返回值,默认返回的是undefined,在TS中 void和undefined不是一回事,
        undefined在TS中是一种明确的简单类型,如果指定返回值为undefined,
        那返回值必须是undefined类型
  • interface接口

    • 在TS中使用interface接口来描述对象数据的类型,常用语给对象的属性和方法添加类型约束 -

      interface Person {
          name: string
          age: number
      }
      ​
      const p: Person = {
          name: 'jack',
          age: 18
      }
    • 使用场景

      • 前端向后端发送数据:手机表单对象数据时的类型校验

      • 前端使用后端数据:渲染那后端对象数组列表时的只能提示

      • 接口的可选设置 -

          interface Props {
            type: string 
              size?: string 
          }
          
          此时size可以不穿,但如果传必须保证类型匹配
      • 接口的继承 -

          // 原价商品类型
          interface GoodsType {
          	id: string 
              price: number
          }
          // 打折商品类型
          interface DisGoodsType {
          	id: string
              price: number
              disPrice: number
          }
          
          此时打折商品类型的属性包含了原价商品类型,此时就可以使用extends实现接口继承,实现类型复用
          以下为使用extends的内容
          
          // 原价商品类型
          interface GoodsType {
          	id: string 
              price: number
          }
          // 打折商品类型
          interface DisGoodsType extends GoodsType {
          	disPrice: number
          }
        
  • type注解对象类型

    • 注解对象

      • 在TS中对于对象数据的类型注解,除了使用interface之外还可以使用类型别名来注解 -

        type Person = {
        	name: string 
            age: number
        }
        const p: Person = {
        	name:'jack',
            age:18
        }
        
    • type + 交叉类型模拟继承 -

        type GoodsType = {
        	id: string 
            price:number
        }
        type DisGoodsTYpe = GoodsType & {
        	disPrice: number
        }
      
    • interface对比 type

      • 相同点

        • 都能描述对象类型

        • 都能实现继承, interface使用extends,type配合交叉类型

      • 不同点

        • type除了能描述对象还可以用来自定义其他类型

        • 同名的interface会合并,属性去并集,不能出现类型冲突,同名他也配会报错

      • 推荐使用type,type更灵活

  • 字面量类型

    • 使用js字面量 作为类型对变量进行类型注释,这种类型就是字面量类型,字面量类型比普通类型更加精确 -

        // 普通number类型,可以赋值任何数值
        let count: number 
        
        // 字面量类型100, 只能赋值为100
        let count1: 100
        count1 = 100 (只能为100)
      
    • 字面量类型的实际应用 -

        type Gender = '男' | '女'
        let gender: Gender = ''(只能为男或女)
      
    • 字面量与const

      • const声明的变量为常量,不可以重新赋值,故const声明的为字面量类型而不是string类型

  • 类型推论和any类型

    • 类型推论

      • 在TS中存在类型推断机制,在咩有给变量添加类型注解的情况下,TS也会给变量提供类型

    • any类型

      • 变量被注解为any类型之后,TS会忽略类型检查,错误的类型赋值不会报错,也不会有任何提示 -

        let obj: any = { age: 18 }	(此时obj只有age并且为字面量类型)
        obj.bar = 100				(此时有了bar并且为number类型)
        obj()
        const n: number = obj 		(此时的obj也可以给字面量类型赋值)
        
    • 类型断言

      • 有时开发者比TS本身更清楚当前的类型是什么,可以使用断言(as) 让类型更加精确和具体 -

        需求:获取页面的ID为link的a元素,尝试用过点语法访问href属性
        
        const aLink = document.getElementById('link')  (此时TS会认为aLink为 HTMLElement | null)
        我们知道只为 HTMLAnchorElement 不会为 null
        const aLink1 = document.getElementById('link') as HTMLAnchorElement
        
    • 类型断言的注意事项

      • 类型断言只能欺骗TS编译器,无法避免运行时的错误,滥用类型断言可能会导致运行时错误

  • 泛型

    • 泛型是指在定义接口、函数等类型的时候,不预定制定具体的类型,而在使用的时候再指定类型的一种特性,使用泛型可以复用类型并且让类型更加灵活

    • 泛型接口

      • 在接口类型的名称后面使用<T>即可声明一个泛型参数,接口里的其他成员都能使用该参数的类型

      • interface ResData<T> {} -

        // 定义泛型
        interface ResData<T> {
        	msg: string 
            code: number
            data: T
        }
        
        // 定义具体类型
        interface User {
        	name: string 
            age: number
        }
        // 使用泛型并传入具体类型
        let useData: ResData<User> {
        	code: 200,
            msg: 'message',
            data: {
            	name: 'jack',
                age: 18
            }
        }
        
    • 泛型别名

      • 在类型别名的type的后面使用<T>即可声明一个泛型参数,接口里的其他成员都能使用该参数的类型

      • type ResData<T> {} -

        // 定义泛型
        type ResData<T> {
            msg: string 
            code: number
            data: T
        }
        ​
        // 定义具体类型
        type User {
            name: string 
            age: number
        }
        // 使用泛型并传入具体类型
        let useData: ResData<User> {
            code: 200,
            msg: 'message',
            data: {
                name: 'jack',
                age: 18
            }
        }
    • 泛型约束

      • 泛型的特点就是灵活不确定,有些时候泛型函数的内部需要访问一些特定类型的数据才有的属性,此时会有类型错误,需要通过泛型约束解决 -

        function logLen<T>(obj: T) {
            console.log(obj.length)  // 此时length报错
        }
        ​
        // 定义接口
        interface LengthObj {
            length: number
        }
        // 泛型约束
        function logLen<T extends lengthObj>(obk: T) {
            console.log(obj.length)
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值