深入浅出TypeScript | 青训营笔记

88 阅读6分钟

本课程从TS基础入手,由基础类型一步步延伸到高级类型,通过示例来深入浅出的了解TypeScript的各种姿势。

课程重点

  • 整体介绍:Ts 背景、优缺点、社区活跃度等

  • TS常用类型基本概念

    • 基础类型、对象类型、接口、断言等
  • 进阶用法

    • 类、泛型及使用场景
  • 工程向

    • 代码检测、编译配置、tsconfig介绍
    • 工程中最佳实践、迁移工具
  • 小练习:实践一下

为什么要学习TS

TypeScript是JavaScript类型的超集,它可以编译成纯JavaScript.

TypeScript可以在任何浏览器、任何计算机和任何操作系统上运行,并且是开源的.

image.png TS特性:类型安全(和Java,C++一样),TS包含了一些编译器,有着JS特性,完善的工具链(TS不仅仅是一门语言,更是一个工具)

TS学习推荐

Awesome Typescript: TS开源教程及应用

ByteTech: TS&React:React + TypeScript开发模式介绍

Typescript Playground: TS到JS在线编译

TS基础

基础类型

image.png

number包含了整数,浮点数,负数(JS拓展)

枚举是TS特有的类型,可以对枚举事件进行定义

image.png enum定义枚举,TypeScript会为它们每个值分配编号,默认从0开始,在使用时,就可以使用名字而不需要记数字和名称的对应关系了(在仅指定常量命名的情况下,定义的就是一个默认从 0 开始递增的数字集合,称之为数字枚举。如果想要从其他值开始递增,可以将第一个值的索引值进行指定)。可以看出TS不光是对枚举池和变量进行了映射,还进行了反映射

TypeScript 将定义值是字符串字面量的枚举称为字符串枚举,字符串枚举值要求每个字段的值都必须是字符串字面量,或者是该枚举值中另一个字符串枚举成员(注意,这里的其他枚举成员指的是同一个枚举值中的枚举成员

image.png

`
{
    200: "Success",
    404: "NotFound",
    500: "Error",
    Error: 500,
    NotFound: 404,
    Success: 200
}`

异构枚举就是枚举值中成员值既有数字类型又有字符串类型

在TypeScript中,定义了枚举值之后,编译成 JavaScript 的代码会创建一个对应的对象,这个对象可以在程序运行时使用。但是如果使用枚举只是为了让程序可读性好,并不需要编译后的对象呢?这样会增加一些编译后的代码量。TypeScript 中有一个const enum(常量枚举),在定义枚举的语句之前加上const关键字,这样编译后的代码不会创建这个对象,只是会从枚举里拿到相应的值进行替换

image.png

如果枚举值里所有成员都是字面量类型的值,那么枚举的每个成员和枚举值本身都可以作为类型来使用,我们称这样的枚举成员为字面量枚举成员。满足条件的枚举成员的值有以下三种:

  • 没有初始值的枚举成员,例如:enum E { A }
  • 值为字符串字面量,例如:enum E { A = 'a' }
  • 值为数值字面量,或者带有-符号的数值字面量,例如:enum E { A = 1 }enum E { A = -1 }

(1)枚举成员类型

当所有枚举成员都拥有字面量枚举值时,就枚举成员成为了类型:

enum Animal {
  Dog = 1,
  Cat = 2
}

interface Dog {
  type: Animal.Dog; 
}
interface Cat {
  type: Animal.Cat; 
}

let cat: Cat = {
  type: Animal.Dog // error [ts] 不能将类型“Animal.Dog”分配给类型“Animal.Cat”
};
let dog: Dog = {
  type: Animal.Dog
};

可以看到,代码的第七行使用Animal.Dog作为类型,指定接口Dog的必须有一个type字段,且类型为Animal.Dog。

(2)联合枚举类型

当枚举值符合条件时,这个枚举值就可以看做是一个包含所有成员的联合类型

enum Status {
  Off,
  On
}
interface Light {
  status: Status;
}
enum Animal {
  Dog = 1,
  Cat = 2
}
const light1: Light = {
  status: Animal.Dog // error 不能将类型“Animal.Dog”分配给类型“Status”
};
const light2: Light = {
  status: Status.Off
};
const light3: Light = {
  status: Status.On
};

上面例子定义接口 Light 的 status 字段的类型为枚举值 Status,那么此时 status 的属性值必须为 Status.Off 和 Status.On 中的一个,也就是相当于status: Status.Off | Status.On

枚举合并

说完常见的枚举类型,最后来看看枚举合并的概念。对于枚举类型的值,我们可以分开进行声明:

enum Day {
  SUNDAY,
  MONDAY,
  TUESDAY
 }

enum Day {
  WEDNESDAY,
  THURSDAY,
  FRIDAY,
  SATURDAY
 }

这时 TypeScript 就会对这个枚举值进行合并操作,合并后编译为JavaScript的代码如下:

var Day = void 0;
(function (Day) {
  Day[Day["SUNDAY"] = 0] = "SUNDAY";
  Day[Day["MONDAY"] = 1] = "MONDAY";
  Day[Day["TUESDAY"] = 2] = "TUESDAY";
  Day[Day["WEDNESDAY"] = 3] = "WEDNESDAY";
  Day[Day["THURSDAY"] = 4] = "THURSDAY";
  Day[Day["FRIDAY"] = 5] = "FRIDAY";
  Day[Day["SATURDAY"] = 6] = "SATURDAY";
})(Day || (Day = {}));

unknown其实是enum的一个替代类型,允许赋值和反向赋值,enum不允许反向,检测更安全一点

never表示永远不存在值的类型

image.png

元组类型是数组的一个特殊形式,需要显式标示数组中每一个元素的类型

函数类型

image.png

接口

对象类型:具体的js对象,描述键值对

image.png

public默认,private继承和实例都不能调用,protected仅支持继承类可以调用

image.png

image.png

TS进阶

高级类型

联合类型|、交叉类型&

image.png

注意:同名类型取交集,同名的非基础类型的合并会进行一些相关元素的一些组合关系

类型断言

告诉编译器这个类型一定会有我需要的类型,省去了一些相关类型推断,也是让编译器不会进行错误的类型抛出,手动指定类型(断言:告诉某个实例具体类型 语法:as 类型

image.png

类型别名(type) VS intface

定义:给类型起个别名

-相同点:

  • 1.都可以定义对象或函数
  • 2.都允许继承
  • 差异点:
  • 1.interface是TS用来定义对象,type是用来定义别名方便使用
  • 2.type可以定义基本类型,interface不行;
  • 3.interface可以合并重复声明,type不行;

高级类型中涉及到泛型的

官方定义

软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型这在创建大型系统时为你提供了十分灵活的功能。 在像 C# 和Java 这样的语言中,可以使用泛型来创建可重用的组件一个组件可以支持多种类型的数据。这样用户就可以以自己的数据类型来使用组件。

image.png

image.png

泛型基础操作符

image.png

image.png

泛型常用工具类型

image.png

实战和工程向

声明文件

declare声明环境上下文中我们需要哪些数据类型

  • declare:三方库需要类型声明文件
  • .d.ts:声明文件定义
  • @types:三方库TS类型包
  • tsconfig.json:定义TS的配置

image.png

课程总结

image.png