一切福田,不離方寸,從心而覓,感無不通。

[ 万字总结 ] 夯实你的 TypeScript 基础

1.环境配置和搭建

一.什么是Typescript

TypeScriptJavascript的超集,遵循最新的ES5/ES6规范。Typescript扩展了Javascript语法。

  • Typescript更像后端JAVA,让JS可以开发大型企业应用
  • TS提供的类型系统可以帮助我们在写代码时提供丰富的语法提示
  • 在编写代码时会对代码进行类型检查从而避免很多线上错误

TypeScript不会取代JS尤雨溪:  我认为将类型添加到JS本身是一个漫长的过程 。让委员会设计一个类型系统是(根据TC39的经历来判断)不切实际的 。

二.环境配置

1.全局编译TS文件

全局安装typescriptTS进行编译

 

 

2.配置webpack环境

  • 安装依赖

     
  • 初始化TS配置文件

     
  • webpack配置操作

     
  • package.json配置

     

我们可以通过npm run start启动服务来使用typescript啦~

2.基础类型

TS中冒号后面的都为类型标识

一.布尔、数字、字符串类型

 

二.元组类型

限制长度个数、类型一一对应

 

三.数组

声明数组中元素数据类型

 

四.枚举类型

 

可以枚举,也可以反举

 

  • 异构枚举

     
  • 常量枚举

     

五.any类型

不进行类型检测

 

六.null 和 undefined

任何类型的子类型,如果strictNullChecks的值为true,则不能把null 和 undefined付给其他类型

 

七.void类型

只能接受null,undefined。一般用于函数的返回值

 

严格模式下不能将null赋予给void

八.never类型

任何类型的子类型,never代表不会出现的值。不能把其他类型赋值给never

 

九.Symbol类型

Symbol表示独一无二

 

十.BigInt类型

 

number类型和bigInt类型是不兼容的

十一.object对象类型

object表示非原始类型

 

3.类型推导

一.类型推导

  • 声明变量没有赋予值时默认变量是any类型

     
  • 声明变量赋值时则以赋值类型为准

     

二.包装对象

我们在使用基本数据类型时,调用基本数据类型上的方法,默认会将原始数据类型包装成对象类型

 

boolean是基本数据类型 , Boolean是他的封装类

三.联合类型

在使用联合类型时,没有赋值只能访问联合类型中共有的方法和属性

 

这里的!表示此值非空

 

四.类型断言

  • 类型断言

     

    尽量使用第一种类型断言因为在react中第二种方式会被认为是jsx语法

  • 双重断言

     

    尽量不要使用双重断言,会破坏原有类型关系,断言为any是因为any类型可以被赋值给其他类型

五.字面量类型

 

可以用字面量当做类型,同时也表明只能采用这几个值(限定值)。类似枚举。

4.函数类型

一.函数的两种声明方式

  • 通过function关键字来进行声明

     

    可以用来限制函数的参数和返回值类型

  • 通过表达式方式声明

     

二.可选参数

 

三.默认参数

 

四.剩余参数

 

五.函数的重载

 

5.类

一.TS中定义类

 

实例上的属性需要先声明在使用,构造函数中的参数可以使用可选参数和剩余参数

二.类中的修饰符

  • public修饰符(谁都可以访问到)

     

     

    我们可以通过参数属性来简化父类中的代码

  • protected修饰符 (自己和子类可以访问到)

     
  • private修饰符 (除了自己都访问不到)

     
  • readonly修饰符 (仅读修饰符)

     

三.静态属性和方法

 

静态属性和静态方法是可以被子类所继承的

四.Super属性

 

五.类的装饰器

1.装饰类

 

装饰类可以给类扩展功能,需要开启experimentalDecorators:true

2.装饰类中属性

 

装饰属性可以对属性的内容进行改写,装饰的是实例属性则target指向类的原型、装饰的是静态属性则target执行类本身~

3.装饰类中方法

 

4.装饰参数

 

六.抽象类

抽象类无法被实例化,只能被继承,抽象方法不能在抽象类中实现,只能在抽象类的具体子类中实现,而且必须实现。

 

定义类型时void表示函数的返回值为空(不关心返回值类型,所有在定义函数时也不关心函数返回值类型)

6.接口

接口可以在面向对象编程中表示行为的抽象,也可以描述对象的形状。 接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。 (接口中不能含有具体的实现逻辑)

一.函数接口参数

 

我们可以约束函数中的参数,但是类型无法复用

 

我们可以通过接口进行描述

二.函数类型接口

 

通过接口限制函数的参数类型和返回值类型

三.函数混合类型

 

四.对象接口

对象接口可以用来描述对象的形状结构

 

?标识的属性为可选属性, readOnly标识的属性则不能修改。多个同名的接口会自动合并

 

五.任意属性、可索引接口

 

任意属性可以对某一部分必填属性做限制,其余的可以随意增减

 

可索引接口可以用于标识数组

六.类接口

这里先来强调一下抽象类和接口的区别,抽象类中可以包含具体方法实现。接口中不能包含实现

 

一个类可以实现多个接口,在类中必须实现接口中的方法和属性

七.接口继承

 

八.构造函数类型

 

这里无法标识返回值类型

 

new() 表示当前是一个构造函数类型,这里捎带使用了下泛型。 在使用createClass时动态传入类型。

7.泛型

一.指定函数参数类型

  • 单个泛型

 

  • 多个泛型

 

二.函数标注的方式

  • 类型别名

 

可以使用类型别名,但是类型别名不能被继承和实现。一般联合类型可以使用类型别名来声明

  • 接口

 

能使用interface尽量使用interface

三.泛型接口使用

 

四.默认泛型

 

可以指定泛型的默认类型,方便使用

五.类中的泛型

  • 创建实例时提供类型

 

  • 校验构造函数类型

 

六.泛型约束

  • 泛型必须包含某些属性

 

 

  • 返回泛型中指定属性

 

8.兼容性

TS中的兼容性,主要看结构是否兼容。(核心是考虑安全性)

一.基本数据类型的兼容性

 

你要的我有就可以

 

二.接口兼容性

 

接口的兼容性,只要满足接口中所需要的类型即可!

三.函数的兼容性

函数的兼容性主要是比较参数和返回值

  • 参数

     

    赋值函数的参数要少于等于被赋值的函数,与对象相反,例如:

     

  • 返回值

     

四.函数的逆变与协变

函数的参数是逆变的,返回值是协变的 (在非严格模式下函数的参数是双向协变的)

 

通过这个案例可以说明,函数参数可以接收父类,返回值可以返回子类

五.类的兼容性

 

这里要注意的是,只要有private或者protected关键字类型就会不一致;但是继承的类可以兼容

 

六.泛型的兼容性

 

七.枚举的兼容性

 

9.类型保护

通过判断识别所执行的代码块,自动识别变量属性和方法

一.typeof类型保护

 

二.instanceof类型保护

 

三.in类型保护

 

四.可辨识联合类型

 

五.null保护

 

这里要注意的是ts无法检测内部函数变量类型

六.自定义类型保护

 

七.完整性保护

 

10.类型推断

一.赋值推断

赋值时推断,类型从右像左流动,会根据赋值推断出变量类型

 

二.返回值推断

自动推断函数返回值类型

 

三.函数推断

函数从左到右进行推断

 

四.属性推断

可以通过属性值,推断出属性的类型

 

五.类型反推

可以使用typeof关键字反推变量类型

 

六.索引访问操作符

 

七.类型映射

 

11.交叉类型

交叉类型(Intersection Types)是将多个类型合并为一个类型

 

举例:我们提供两拨人,一拨人都很帅、另一拨人很高。我们希望找到他们的交叉部分 => 又高又帅的人

  • 交叉类型

 

 

12.条件类型

一.条件类型基本使用

可以使用extends关键字和三元表达式,实现条件判断

 

二.条件类型分发

 

这里会用每一项依次进行分发,最终采用联合类型作为结果,等价于:

 

三.内置条件类型

  • 1.Exclude排除类型

 

  • 2.Extract抽取类型

 

  • 3.NoNullable 非空检测

 

四.infer类型推断

  • 1.ReturnType返回值类型

 

  • 2.Parameters 参数类型

 

  • 3.ConstructorParameters构造函数参数类型

 

  • 4.InstanceType 实例类型

 

五.infer实践

将数组类型转化为联合类型

 

将两个函数的参数转化为交叉类型

 

表示要把T1T2赋予给x,那么x的值就是T1T2的交集。(参数是逆变的可以传父类)

TS的类型:TS主要是为了代码的安全性来考虑。所以所有的兼容性问题都要从安全性来考虑!

13.内置类型

一.Partial转化可选属性

遍历所有的属性将属性设置为可选属性,但是无法实现深度转化!

我们可以实现深度转化,如果值是对象继续深度转化。

二.Required转化必填属性

将所有的属性转化成必填属性

三.Readonly转化仅读属性

将所有属性变为仅读状态

四.Pick挑选所需的属性

在已有类型中挑选所需属性

五.Record记录类型

实现map方法,我们经常用record类型表示映射类型

六.Omit忽略属性

忽略person中的address属性 (先排除掉不需要的key,在通过key选出需要的属性)

14.装包和拆包

一.装包

二.拆包

15.自定义类型

一.Diff实现

求两个对象不同的部分

二.InterSection交集

三.Overwrite属性覆盖

如果存在已有属性则使用新属性类型进行覆盖操作

四.Merge对象合并

将两个对象类型进行合并操作

16.unknown

一.unknown类型

unknown类型,任何类型都可以赋值为unknown类型。 它是 any 类型对应的安全类型

不能访问unknown类型上的属性,不能作为函数、类来使用

  • 联合类型中的unknown

    联合类型与unknown都是unknown类型

  • 交叉类型中的unknown

    交叉类型与unknown都是其他类型

二.unknown特性

  • never是unknown的子类型
  • keyof unknown 是never
  • unknown类型不能被遍历

unknown类型不能和number类型进行 +运算,可以用于等或不等操作

17.模块和命名空间

默认情况下 ,我们编写的代码处于全局命名空间中

一.模块

文件模块: 如果在你的 TypeScript 文件的根级别位置含有 import 或者 export,那么它会在这个文件中创建一个本地的作用域 。

二.命名空间

命名空间可以用于组织代码,避免文件内命名冲突

  • 命名空间的使用
  • 命名空间嵌套使用

命名空间中导出的变量可以通过命名空间使用。

18.类型声明

一.声明全局变量

  • 普通类型声明

类型声明在编译的时候都会被删除,不会影响真正的代码。目的是不重构原有的js代码,而且可以得到很好的TS支持

练习: 声明jQuery类型

jquery通过外部CDN方式引入,想在代码中直接使用

  • 命名空间声明

namespace表示一个全局变量包含很多子属性 , 命名空间内部不需要使用 declare 声明属性或方法

二. 类型声明文件

类型声明文件以.d.ts结尾。默认在项目编译时会查找所有以.d.ts结尾的文件

三.编写第三方声明文件

配置tsconfig.json

  • jquery声明文件

  • events模块声明文件

四.模块导入导出

五.第三方声明文件

@types是一个约定的前缀,所有的第三方声明的类型库都会带有这样的前缀

当使用jquery时默认会查找 node_modules/@types/jquery/index.d.ts 文件

查找规范

  • node_modules/jquery/package.json 中的types字段
  • node_modules/jquery/index.d.ts
  • node_modules/@types/jquery/index.d.ts

19.扩展全局变量类型

一.扩展局部变量

可以直接使用接口对已有类型进行扩展

二.模块内全局扩展

声明全局表示对全局进行扩展

三.声明合并

同一名称的两个独立声明会被合并成一个单一声明,合并后的声明拥有原先两个声明的特性。

1.同名接口合并

2.命名空间的合并

  • 扩展类
  • 扩展方法
  • 扩展枚举类型

3.交叉类型合并

四.生成声明文件

配置tsconfig.json 为true 生成声明文件

完结撒花

以上就是 TypeScript 基础的全部啦,掌握了这些对于面试已经是绰绰有余,不过对于语言来说还是需要多加练习哟。欢迎点赞收藏 !

作者:我_舅是太阳
链接:https://juejin.cn/post/7102384712504573982

链接:https://juejin.cn/post/7102996554541170696
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。