• TS 入门指南


    TS 类型基本用法

    TS简介

    • TypeScript,简称 TS, 是一种由微软开发的编程语言,它是对 JavaScript 的一个增强
    • 让我们更加方便地进行类型检查和代码重构,提高代码的可靠性和可维护性
    • 同时,TypeScript 还支持 ECMAScript 的最新特性

    搭建学习环境 

    进入 Node 官网安装

    安装完成后使用以下命令查看是否安装完成: 安装完成后使用以下命令查看是否安装完成: 

    • node -v
    • npm -v

    继续安装 nrm 管理包源:

    • npm i nrm -g
    • nrm ls
    • nrm use taobao

    全局安装 typescript:

    • npm i typescript -g

    全局安装 ts 的编译工具,使用 ts-node 可以将 ts 文件执行

    • npm i ts-node -g
      • 使用:ts-node index.ts
    • 安装 ts-node 依赖包:npm install tslib @types/node -g

    使用 TS 可以有良好的提示,使代码可读性变强,更提前发现问题

    TS 类型

    • TS 出现弥补的 JS 的类型缺失
    • 众所周知,代码错误越早发现越好,代码编写 > 代码编译 > 代码运行 开发 > 测试 > 上线
    • Vue2 使用 Flow 进行类型检查,后续 Vue3 也使用 Typescript 重写
    • TS 代码要运行在浏览器,需要进行类型擦除,转换为 JS 代码
    • TS 类型包含所有 JS 类型 null、undefined、string、number、boolean、bigInt、Symbol、object(数组,对象,函数,日期)
    • 还包含 void、never、enum、unknown、any 以及 自定义的 type 和 interface

    变量声明

    • var/let/const 标识符: 数据类型 = 赋值

    手动指定数据的类型(类型注解),不要写成大写的 String ,因为这是 JS 的一个内置类

    const data: string = 'hello'

    型定义的时候已经决定

    类型推导

    • 如果没有明确指定类型,TS 会隐式的推导出一个类型
    • 这类型根据赋值的类型推断,没有赋值则为 any 类型,能自动推导出类型,没必要手动指定

     基础类型

     

    数组和元组 

    1. Array<元素类型>这种写法可能会存在与jsx冲突问题
    2. const arr1: Array = [1, 2, 3]
    3. 元素类型后面接上[],表示由此类型元素组成的一个数组
    4. [const arr2: number[] = [1, 2, 3]
    5. 数组里面可能有字符串和数组
    6. const arr3: (string | number)[] =
    7. [1,2,'黛玉']
    8. //元组已知元素数量和类型的数组,元组一定要指明类型
    9. const tuple:[string, number] = ['云牧', 18]

    • tuple可以作为函数返回的值,React 的 useState 就是个元组,类似于
    1. function useState(state: T): [T, (newState: T)=> void]
    2. let currentState = state
    3. const changeState = newState
    4. currentState = newState
    5. }
    6. return [currentState, changeState]
    7. [const [count, setCount]= useState(10)

    对象类型

    • TS 中的 object 类型泛指所有的的非原始类型,如对象、数组、函数
    • 下面我们使用 object 声明了这个对象,但是这个对象既不能设置新数据,也不能修改老数据
    1. const obj: object = {
    2. name:'云牧',
    3. }
    4. obj.age = 18
    5. obj.name='黛玉'

    • 下面这种对象类型的限制才更为精确
    • 可限制对象每个属性的类型
    1. const p1:{name: string; age:number } = { name:'黛玉',age:18}
    2. // 问号,代表某个属性可选,不一定需要
    3. const p2: { name: string; age?: number } = {I name:'云牧'}

    any、unknown、never

    • 无法确定一个变量的类型,可使用 any,此时在其身上做任何操作都是合法的,即使访问了一个不存在的属性
    • 如果某些情况处理类型过于繁琐,或者在引入一些第三方库时,缺失了类型注解,这个时候 我们可以使用 any,更多是为了兼容老代码
    1. function anyType(msg: any) {
    2. console.log(msg)
    3. }

    • unknown 类型表示一个值可以是任何类型,它是所有类型的父类型,任何类型都可以赋值给 unknown 类型,但是 unknown 类型只能赋值给 any 类型和 unknown 类型本身
    • 类似 any,与 any 类型不同的是,unknown 类型的变量不能直接赋值给其他类型的变量,也不能调用其上的任何方法或属性,除非先进行类型检查或类型断言,这样确保运行时的类型安全
    • 默认在其操作都是不合法的,主要是在编写通用代码时,例如编写库或框架时,需要处理来自不同来源的数据,但又不确定数据的类型
    1. //类型判断后才能使用 unknown类型数据
    2. function foo(arg: unknown) {
    3. if (typeof arg == 'string') {
    4. console.log(arg.toUpperCase())
    5. } else if (typeof arg == 'number') {
    6. console.log(arg.toFixed(2))
    7. }
    8. }
    9. //类型断言后使用
    10. function bar(arg: unknown) {
    11. const num = arg as number
    12. console.log(num.toFixed(2))
    13. }

    • 假如一个函数的返回结果是死循环或者异常,我们可以使用 never 类型表示这种永不存在值的类型
    • 它是一个底层类型,不是任何类型的子类型,也没有任何子类型
    • 更多情况是封装工具库时候可以使用,比如下面这段代码,如果单纯在函数参数的类型多加一个参数,而没有对应 case 处理,则会报错
    1. function handleMsg(msg: string | number) {
    2. switch (typeof msg) {
    3. case 'string
    4. break
    5. }
    6. case 'number':
    7. break
    8. default: {
    9. const check: never = msg
    10. }
    11. handleMsg('hello')
    12. handleMsg(10)

     never 会在联合类型被直接移除

    函数类型

    • 声明函数时,可以在每个参数后添加类型注解,声明其参数类型
    • 同样也可以声明返回值的类型,不过也可以不写让 TS 自动推导
    • 函数参数的一般顺序 必传参数 - 有默认值的参数 - 可选参数

     

    枚举类型

    • 枚举类型将一组可能出现的值,一个个列举,定义在一个类型中,这个类型就是枚举

     

    这种字符串的枚举可能使用 type Direction = 'LEFT' | 'RIGHT' | 'TOP' | 'RIGHT'可能会更好点 

    1. type Direction = 'LEFT'|'RIGHT'|'TOP'|'BOTTOM'
    2. function turnDirection(direction: Direction) {}
    3. turnDirection('LEFT')

    interface 和 type

    基本使用

    • 使用 interface 定义接口,使用 type 定义类型别名
    • 都可以约束对象的结构
    1. // 方式一:使用interface
    2. interface IPoint{
    3. x: number
    4. readonly y: number // readonly代表只读
    5. z?:number //?代表可选
    6. }
    7. // 方式二:使用type
    8. type Point = {
    9. X: number
    10. y: number
    11. }

    区别

    1. interface 只描述对象,type 则可以描述所有数据
    2. interface 使用 extends 来实现继承,type 使用 & 来实现交叉类型
    3. interface 会创建新的类型名,type 只是创建类型别名,并没有创建新类型
    4. interface 可以重复声明扩展,type 则不行(别名是不能重复的)

     索引签名(Index Signatures)

    接口继承

    • 接口和类继承相同,都是使用 extends 关键字
    • 接口是支持多继承的(类不支持多继承)

    1. interface Animal {
    2. running: () => void
    3. }
    4. interface Person{
    5. name: string
    6. age: number
    7. }
    8. //自动扩展 Person类型
    9. interface Person {
    10. sex: string
    11. }
    12. // 手动使用 extends 继承
    13. interface Student extends Person, Animal {
    14. id: number
    15. }
    16. const u: Student = { name:'云牧',age:18, sex: 'male', id: 1, running() }

    接口实现

    • 定义的接口可以被类实现
    • 之后如果需要传入接口的地方,同样也可以将类实例传入
    • 这就是面向接口开发

    1. interface IRun {
    2. running: () => void
    3. }
    4. interface IEating {
    5. eating:() => void
    6. }
    7. class Person implements IRun, IEating {
    8. running(){}
    9. eating(){}
    10. }
    11. function run(runner: IRun) {
    12. runner.running()
    13. }
    14. constp = new Person()
    15. run(p)

  • 相关阅读:
    【Java面试】大厂裁员,小厂倒闭,如何搞定面试官Java SPI是什么?有什么用?
    数据大屏设计思路 6点
    SAS|lag和dif函数
    使用$test$plusargs提高RTL验收速度
    基于快速行进平方法的水面无人船路径规划
    对于云原生时代的后端业务开发和项目系统学习,选Go Or Java?
    常见面试题-MySQL专栏(三)MVCC、BufferPool
    分类预测 | MATLAB实现WOA-CNN-GRU-Attention数据分类预测
    Spring核心问题回顾2:Spring中用到的设计模式
    Linux 进程层次分析
  • 原文地址:https://blog.csdn.net/weixin_43340372/article/details/134009797