为什么要用 TypeScript

先介绍两个概念哈:

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

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

静态类型语言的优点

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

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


类型系统

TypeScript 引入了类型系统

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

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

类型标注

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

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

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

1
var 变量名: 类型 = 值;

类型检测

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

在这里插入图片描述

小结

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


所有类型

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

  • 基础类型
  • 空和未定义类型
  • 对象类型
  • 数组类型
  • 元组类型
  • 枚举类型
  • 无值类型
  • Never 类型
  • 任意类型
  • 未知类型(Version3.0 Added)

基本类型

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

空、未定义类型

1
2
3
// 空、未定义
var a: null;
var b: undefined;

有以下几个场景需要注意

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

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述

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

比方说下面这个例子:
在这里插入图片描述

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

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

添加完之后就会报错了:
在这里插入图片描述

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

以下就是不够严谨的代码:
在这里插入图片描述
可以通过这样改,就可以避免给 null 元素赋值了
在这里插入图片描述


对象类型

内置对象类型

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

在这里插入图片描述

自定义对象类型

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

1
2
3
4
5
let user: { username: string; age: number } = {
username: "Ruby",
age: 20,
// gender: '男',
};

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

在这里插入图片描述
如果要定义很多个对象,其结构都是统一的,一个个像如下图这样定义的话就很麻烦
在这里插入图片描述
解决的办法就是用接口

接口 interface

接口的使用,首先定义一个接口,然后再创建对象的时候使用它。
在这里插入图片描述
它的优点当然明显了,就是复用性高,但是他也有缺点,即:接口只能作为类型标注使用,不能作为具体值,它只是一种抽象的结构定义,并不是实体,没有具体功能实现

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

类与构造函数

在这里插入图片描述

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

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

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


扩展:包装对象

在这里插入图片描述
字符串对象String > 字符串 string

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

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


数组类型

定义数组有以下几种方法,可以看到也是有类型检测的
在这里插入图片描述


元组类型

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

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

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

在这里插入图片描述


枚举类型

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

在这里插入图片描述

注意事项:

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

可以观察以下编译后的代码
在这里插入图片描述


无值类型

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

在这里插入图片描述

在 strictNullChecks 为 false 的情况下,undefined 和 null 都可以赋值给 void ,但是当 strictNullChecks 为 true 的情况下,只有 undefined 才可以赋值给 void

在这里插入图片描述

Never 类型(不常用)

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

1
2
3
function fn(): never {
throw new Error("error");
}

任意类型

在这里插入图片描述

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

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

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

在这里插入图片描述

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

在这里插入图片描述

未知类型 (3.0 版本新增)

unknown 的用法跟 any 差不多,但是 unknown 比 any 更安全,更严格。
在这里插入图片描述

函数类型

主要就是返回值的类型,注意声明的位置
在这里插入图片描述

git 地址

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