TypeScript 高频面试题整理

306 阅读4分钟

一、基础概念类

介绍一下 TypeScript

TypeScript 是微软开发的开源编程语言,是 JavaScript 的超集,遵循 Apache 2.0 开源协议。它在 JS 语法基础上,增加了静态类型系统,支持类型定义、接口、泛型等特性,代码需编译(通过 tsc 等工具)为 JS 才能在浏览器 / Node.js 环境运行,可有效提升代码可读性、可维护性,降低 bug 率,常用于大型前端工程开发。

TypeScript 和 JavaScript 相比有什么优势

  • 类型检查:TS 编译阶段就能发现类型不匹配错误,JS 需运行时暴露问题,提前规避大量潜在 bug。
  • 代码可读性:类型定义让代码逻辑、数据结构更清晰,团队协作时,他人易理解参数、返回值等含义。
  • 工具支持:编辑器(如 VS Code)可借助类型信息实现智能提示、代码跳转,开发效率更高。
  • 工程化适配:适配大型项目架构,配合接口、泛型等,能更好地进行模块化、组件化开发,代码可维护性更强。

二、核心特性类

介绍一下泛型,一般会用在什么地方

泛型是 TS 中创建可复用、通用组件的工具,让代码逻辑不绑定具体类型。通过 <T>(T 为类型变量,可自定义命名)等语法,定义函数、类、接口时延迟确定类型,调用 / 实例化时再指定。

应用场景

  • 函数复用:比如创建返回值类型与参数类型一致的函数,function identity<T>(arg: T): T { return arg } ,支持 string、number 等多种类型调用。
  • 集合操作:处理数组、映射等数据结构,约束元素类型,如 const list: Array<T> = [] ,保证数组元素类型统一。
  • 类与接口抽象:定义通用类或接口,适配不同业务类型,如网络请求类 class HttpService<T> { ... } ,T 可代表响应数据类型。

介绍一下 interface

Interface(接口)是 TS 用于定义对象结构、规范类型契约的语法。它描述对象应有哪些属性、方法,属性类型及方法参数 / 返回值类型,可用于约束函数参数、类实现,还能实现类型扩展(通过 extends 继承其他接口)。

示例

typescript

interface User {
  name: string;  // 必选属性
  age?: number;  // 可选属性
  readonly id: string;  // 只读属性
  sayHello(): void;  // 方法定义
}

// 函数参数约束
function printUser(user: User) { ... }

// 类实现接口
class Student implements User {
  name = 'xxx';
  id = '123';
  sayHello() { console.log('Hi') }
}

三、工程化与编译类

d.ts 是什么

.d.ts 文件是 TS 的类型定义文件,用于为 JS 代码(或无类型的 TS 代码)补充类型信息。它只包含类型声明(如接口、类型别名、函数 / 变量类型等),不包含实际逻辑,编译时会被 TS 解析,让编辑器能提供类型提示,常见于第三方 JS 库(通过 @types/xxx 安装)或为旧 JS 项目渐进引入 TS 时使用。

示例(为 JS 函数写类型定义):

typescript

// math.js(JS 文件)
function add(a, b) { return a + b }

// math.d.ts(类型定义文件)
declare function add(a: number, b: number): number;

TypeScript 是如何编译的

TS 编译主要依赖 TypeScript 编译器(tsc ,核心流程:

  1. 解析配置:读取项目根目录 tsconfig.json(或通过命令行指定),获取编译选项(如 target 目标 JS 版本、module 模块规范、outDir 输出目录等 )。
  2. 语法解析:将 TS 代码转换为抽象语法树(AST),同时进行类型检查,发现类型错误会抛出警告 / 报错(可配置 noEmitOnError 决定是否停止编译)。
  3. 转译输出:根据 target 等配置,将 TS 语法(如 let/const、箭头函数、泛型等)转译为对应 JS 语法,输出到指定目录(outDir),生成可在浏览器 / Node 环境运行的 JS 文件。

四、模块化与命名空间

讲讲 namespace/module 区别与用法

(1)Module(模块)

  • 定义:TS 中,每个文件默认是一个模块(ES6 模块规范),通过 export 暴露内容,import 引入其他模块,是现代 TS/JS 工程模块化开发的标准方式

  • 用法

    typescript

    // user.ts(模块)
    export interface User { name: string }
    
    // app.ts(引入模块)
    import { User } from './user.ts';
    

(2)Namespace(命名空间)

  • 定义:早期 TS 用于解决全局作用域污染的方案,通过 namespace 包裹代码,创建独立作用域,内部成员需通过 export 暴露,外部通过 namespace.成员 访问,如今在 ES6 模块普及后,使用场景逐渐减少,更推荐用模块方案。

  • 用法

    typescript

    namespace Utils {
      export function formatDate() { ... }
    }
    // 外部使用
    Utils.formatDate();
    

核心区别:Module 基于文件隔离作用域,天然适配工程化拆分;Namespace 是代码块级作用域,依赖手动包裹,现代项目中模块(Module)更主流 。