前端面试 Typescript

71 阅读5分钟

TypeScript 定义

TypeScript 是 JavaScript 的一个超集,主要提供了类型系统和对 ES6 的支持,它由 Microsoft 开发,代码开源于 GitHub 上。

官网的定义:TypeScript 是 JavaScript 的类型的超集,它可以编译成纯 JavaScript。 编译出来的 JavaScript 可以运行在任何浏览器上。 TypeScript 编译工具可以运行在任何服务器和任何系统上。TypeScript 是开源的。

TypeScript 优点

  • TypeScript 增加了代码的可读性和可维护性
    类型系统实际上是最好的文档,大部分的函数看看类型的定义就可以知道如何使用了
    可以在编译阶段就发现大部分错误,这总比在运行时候出错好
    增强了编辑器和 IDE 的功能,包括代码补全、接口提示、跳转到定义、重构等

  • TypeScript 非常包容
    TypeScript 是 JavaScript 的超集,.js 文件可以直接重命名为 .ts 即可
    即使不显式的定义类型,也能够自动做出类型推论
    可以定义从简单到复杂的几乎一切类型
    即使 TypeScript 编译报错,也可以生成 JavaScript 文件
    兼容第三方库,即使第三方库不是用 TypeScript 写的,也可以编写单独的类型文件供 TypeScript 读取

  • TypeScript 拥有活跃的社区
    大部分第三方库都有提供给 TypeScript 的类型定义文件
    Google 开发的 Angular2 就是使用 TypeScript 编写的
    TypeScript 拥抱了 ES6 规范,也支持部分 ESNext 草案的规范

TypeScript 缺点

  • 有一定的学习成本,需要理解接口(Interfaces)、泛型(Generics)、类(Classes)、枚举类型(Enums)等前端工程师可能不是很熟悉的概念

  • 短期可能会增加一些开发成本,毕竟要多写一些类型的定义,不过对于一个需要长期维护的项目,TypeScript 能够减少其维护成本

  • 集成到构建流程需要一些工作量

  • 可能和一些库结合的不是很完美

类型

  • 空值 void
    没有任何类型,可以用 void 表示 没有任何返回值的函数,声明一个 void 类型的变量没有什么用,因为你只能将它赋值为 undefined 和 null

  • 任意类型 any
    有时候我们不确定类型到底是什么的时候,就可以使用 any,让检查器不对这些值进行检查直接通过编译阶段

  • 未知类型 unknown
    和 any 类似。与 any 不同的是,在没有对它进行类型检查之前,unknow 的变量是不能进行任何操作。unknow 更加严格

  • 永不存在 never
    表示永远不存在的类型。比如一个函数永远不会有返回值,函数的返回值就是never类型

  • 联合类型 |
    表示取值可以为多种类型中的一种

  • 交叉类型 &
    就是将多个类型合并为一个类型

枚举类型 Enum

用于取值被限定在一定范围内的场景,比如一周只能有七天,颜色限定为红绿蓝等。

常量枚举

使用 const enum 定义的枚举类型;它会在编译阶段被删除,并且不能包含计算成员

# interface 和 type

一般来说,能用 interface 实现,就用 interface,如果不能就用type

interface

接口,通常用来定义对象的类型,也可以定义 函数、数组、类 的类型

type

类型别名,用来给一个类型起个新名字

相同点

  • 都可以描述一个对象或者函数
  • 都允许拓展。interface 使用 extends;type 使用 &

不同点

  • type 可以使用 typeof 获取实例的类型进行赋值
  • type 可以声明基本类型别名、联合类型、元祖等类型
  • interface 能够声明合并

函数重载

允许一个函数接受不同数量或类型的参数时,作出不同的处理

泛型

将类型也作为变量。在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性

元组

数组合并了相同类型的对象,而元组(Tuple)合并了不同类型的对象

类型推论

如果没有明确的指定类型,那么 TypeScript 会依照类型推论(Type Inference)的规则推断出一个类型。
如果定义的时候没有赋值,不管之后有没有赋值,都会被推断成 any 类型而完全不被类型检查。

类型体操

  • keyof:从对象类型中提取键类型(联合类型)
  • typeof:用来获取一个变量或对象的类型
  • infer:可以推断一个类型变量,这个类型变量只能在true的分支中使用;通常在条件判断时使用(三元运算)
  • is:一般用于函数返回值类型中,判断参数是否属于某一类型,并根据结果返回对应的布尔类型
  • in:在 ts 类型中,类似于遍历;用于取联合类型的值。主要用于数组和对象的构造
  • extends:拓展。可用于 接口继承、类继承、条件判断、泛型约束
  • implements:实现。类实现接口,通常在定义类时使用

类型保护

可以通过 typeofinstanceofin 和 字面量类型 将代码分割成范围更小的代码块,在这一小块中,变量的类型是确定的。

类型保护是指缩小类型的范围,在一定的块级作用域内由编译器推导其类型,提示并规避不合法的操作。

类型保护就是让编译器帮助我们缩小类型范围,在编译阶段规避掉一些不必要的错误,提高代码质量。

命名空间

  • 组织代码,避免命名冲突,避免全局变量造成的污染
  • 命名空间内;默认私有,可以通过 export 暴露
  • 通过 namespace 关键字定义

全局声明

  • 使用declare关键字
  • 全局声明变量和类型

三斜线指令

  • <reference types="..." />:引用第三方声明文件,是node_modules/@types 文件夹下的包,不包含路径信息

  • <reference path="..." />:引用自己写的声明文件,包含路径信息

  • <reference lib="es2019.array" />:引用lib内置声明文件