为什么要用 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:因为在 NullUndefined 这两种类型有且只有一个值,在标注一个变量为 NullUndefined 类型,那就表示该变量不能修改成别的了

在这里插入图片描述

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

在这里插入图片描述

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

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

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

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

解决的办法就是在 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 是可以的

在这里插入图片描述

strictNullChecksfalse 的情况下,undefinednull 都可以赋值给 void ,但是当 strictNullCheckstrue 的情况下,只有 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 差不多,但是 unknownany 更安全,更严格。
在这里插入图片描述

函数类型

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

git 地址

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