文章目录

  • 为什么要用 TypeScript
  • 静态类型语言的优点
  • 类型系统
  • 类型标注
  • 类型检测
  • 小结
  • 所有类型
  • 基本类型
  • 空、未定义类型
  • 对象类型
  • 内置对象类型
  • 自定义对象类型
  • 接口 interface
  • 类与构造函数
  • 扩展:包装对象
  • 数组类型
  • 元组类型
  • 枚举类型
  • 无值类型
  • Never 类型(不常用)
  • 任意类型
  • 未知类型 (3.0 版本新增)
  • 函数类型

为什么要用 TypeScript

先介绍两个概念哈:

动态类型语言:程序运行期间才做数据类型检查的语言,如:JavaScript

静态类型语言:程序编译期间做数据类型检查的语言,如:Java

静态类型语言的优点

  • 程序编译阶段(配合IDE、编辑器甚至可以在编码阶段)即可发现一些潜在错误,避免程序在生产环境运行了以后再出现错误
  • 编码规范、有利于团队开发协作、也更有利于大型项目开发、项目重构
  • 配合IDE、编辑器提供更强大的代码智能提示/检查
  • 代码即文档

这些优点都是基于类型系统的

类型系统

TypeScript 引入了类型系统

类型系统有以下这几个功能:

  • 类型标注(定义、注解)
  • 类型检测(检查)

类型标注

首先大致看一下怎么用的:

// 基本类型
var title: string = 'hello Typescript'; // 字符串类型的标注
var n: number = 1; // 数字类型的标注
var isOk: boolean = true; // 布尔类型的标注

也就是在变量后加冒号,再加类型的声明

var 变量名: 类型 = 值

类型检测

此时如果你试图给 string 类型的变量声明其他类型,ts 就会以报错的形式告诉你(要配合 VSCode 或者支持 TypeScript 的编辑器,才会有一些错误提示,这里就是红色的波浪了)。

Typescript无法对后端做断点调试 跨域 为什么typescript_赋值


如果此时进行编译,他也会报错,这肯定啊。

Typescript无法对后端做断点调试 跨域 为什么typescript_数据_02

小结

从这里就可以知道,我们的类型标注,其实是给 vsCode(或者说是编译器) 看的,告诉编译器这个变量存储的是什么 类型的值,然后编译器才回去检测类型。

所有类型

类型的话有这么一坨,这个不太敢放在前面了,太多了会不会劝退很多人呢?,口区

  • 基础类型
  • 空和未定义类型
  • 对象类型
  • 数组类型
  • 元组类型
  • 枚举类型
  • 无值类型
  • Never 类型
  • 任意类型
  • 未知类型(Version3.0 Added)
基本类型
var title: string = 'hello Typescript'; // 字符串类型的标注
var n: number = 1; // 数字类型的标注
var isOk: boolean = true; // 布尔类型的标注
空、未定义类型
// 空、未定义
var a: null;
var b: undefined;

有以下几个场景需要注意

场景1:因为在 NullUndefined 这两种类型有且只有一个值,在标注一个变量为 NullUndefined 类型,那就表示该变量不能修改成别的了

Typescript无法对后端做断点调试 跨域 为什么typescript_字符串_03

场景2:默认情况下 nullundefined 是所有类型的子类型。 就是说你可以把 nullundefined 赋值给其它类型的变量

Typescript无法对后端做断点调试 跨域 为什么typescript_字符串_04

场景3:默认的值是 undefined,默认的类型是 any

Typescript无法对后端做断点调试 跨域 为什么typescript_赋值_05


Typescript无法对后端做断点调试 跨域 为什么typescript_字符串_06

场景4:比较隐蔽的问题,因为 nullundefined 都是其它类型的子类型,所以默认情况下会有一些隐藏的问题

比方说下面这个例子:

Typescript无法对后端做断点调试 跨域 为什么typescript_赋值_07

解决的办法就是在 tsconfig.json 添加 null 值严格检查

"strictNullChecks": true // null 值严格检查,工作中可以添加

添加完之后就会报错了:

Typescript无法对后端做断点调试 跨域 为什么typescript_赋值_08

null 值的检测,还能够使代码更严谨

以下就是不够严谨的代码:

Typescript无法对后端做断点调试 跨域 为什么typescript_字符串_09


可以通过这样改,就可以避免给 null 元素赋值了

Typescript无法对后端做断点调试 跨域 为什么typescript_字符串_10

对象类型
内置对象类型

JavaScript 中,有许多的内置对象,比如:Object、Array、Date……,我们可以通过对象的 构造函数 或者 来进行标注

Typescript无法对后端做断点调试 跨域 为什么typescript_字符串_11

自定义对象类型

另外一种情况,许多时候,我们可能需要自定义结构的对象。这个时候,我们可以这样:

let user: { username: string; age: number } = {
  username: 'Ruby',
  age: 20,
  //   gender: '男',
};

如果你添加了没有声明的属性,他就会报错

Typescript无法对后端做断点调试 跨域 为什么typescript_字符串_12


如果要定义很多个对象,其结构都是统一的,一个个像如下图这样定义的话就很麻烦

Typescript无法对后端做断点调试 跨域 为什么typescript_字符串_13


解决的办法就是用接口

接口 interface

接口的使用,首先定义一个接口,然后再创建对象的时候使用它。

Typescript无法对后端做断点调试 跨域 为什么typescript_字符串_14

它的优点当然明显了,就是复用性高,但是他也有缺点,即:接口只能作为类型标注使用,不能作为具体值,它只是一种抽象的结构定义,并不是实体,没有具体功能实现

接口只存在 TypeScript 的编译阶段,编译后的 JavaScript 文件中是没有这个的。

类与构造函数

Typescript无法对后端做断点调试 跨域 为什么typescript_数据_15

  • 这个 Person 定义下来之后,是可以直接使用的,这个不像 interface
  • 并且同时定义了new 出来的对象的类型,就是 Person

优点 : 功能相对强大,定义实体的同时也定义了对应的类型

缺点 : 复杂,比如只想约束某个函数接收的参数结构,没有必要去定一个类,使用接口会更加简单

扩展:包装对象

Typescript无法对后端做断点调试 跨域 为什么typescript_数据_16

字符串对象String > 字符串 string

字符串有的东西,字符串对象是一定有的。

如果试图将对象类型赋值给简单类型,这样会丢失数据的。而反过来就不会丢失数据。

数组类型

定义数组有以下几种方法,可以看到也是有类型检测的

Typescript无法对后端做断点调试 跨域 为什么typescript_赋值_17

元组类型

如何向数组中添加类型不同的数据呢?这时候就引入了元组。

元组类似数组,但是存储的元素类型不必相同,但是需要注意:

  • 初始化数据的个数以及对应位置标注类型必须一致
  • 后期,越界数据必须是元组标注中的类型之一(标注越界数据可以不用对应顺序 - 联合类型)\

Typescript无法对后端做断点调试 跨域 为什么typescript_字符串_18

枚举类型

枚举的作用组织收集一组关联数据的方式,通过枚举我们可以给一组有关联意义的数据赋予一些友好的名字

Typescript无法对后端做断点调试 跨域 为什么typescript_字符串_19

注意事项:

  • key 不能是数字
  • value 可以是数字,称为 数字类型枚举,也可以是字符串,称为 字符串类型枚举,但不能是其它值,默认为数字:0
  • 枚举值可以省略,如果省略,则:
  • 第一个枚举值默认为:0
  • 非第一个枚举值为上一个数字枚举值 + 1
  • 如果前一个枚举值类型为字符串,则后续枚举项必须手动赋值
  • 枚举值为只读(常量),初始化后不可修改

可以观察以下编译后的代码

Typescript无法对后端做断点调试 跨域 为什么typescript_赋值_20

无值类型

如果函数返回的是void ,那么他就不能 return null,然而 return undefined 是可以的

Typescript无法对后端做断点调试 跨域 为什么typescript_字符串_21

strictNullChecksfalse 的情况下,undefinednull 都可以赋值给 void ,但是当 strictNullCheckstrue 的情况下,只有 undefined 才可以赋值给 void

Typescript无法对后端做断点调试 跨域 为什么typescript_赋值_22

Never 类型(不常用)

当一个函数永远不可能执行 return 的时候,返回的就是 never ,与 void 不同,void 是执行了 return, 只是没有值,never 是不会执行 return,比如抛出错误,导致函数终止执行

function fn(): never {
  throw new Error('error');
}
任意类型

Typescript无法对后端做断点调试 跨域 为什么typescript_字符串_23

  • 一个变量申明未赋值且未标注类型的情况下,默认为 any 类型
  • 任何类型值都可以赋值给 any 类型

注意:标注为 any 类型,也意味着放弃对该值的类型检测,同时放弃 IDE 的智能提示

想要避免这样的问题,可以在这里写个配置

Typescript无法对后端做断点调试 跨域 为什么typescript_赋值_24

之后就会在代码中报错了(如果不报错的话,重启一下项目试试,有的时候会不报错)

Typescript无法对后端做断点调试 跨域 为什么typescript_字符串_25

未知类型 (3.0 版本新增)

unknown 的用法跟 any 差不多,但是 unknownany 更安全,更严格。

Typescript无法对后端做断点调试 跨域 为什么typescript_数据_26

函数类型

主要就是返回值的类型,注意声明的位置

Typescript无法对后端做断点调试 跨域 为什么typescript_数据_27

git 地址

https://gitee.com/lovely_ruby/DailyPractice/tree/main/front/advanced_class/16_typescript/recording/src/01_%E7%B1%BB%E5%9E%8B