一、基础概念类
介绍一下 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) ,核心流程:
- 解析配置:读取项目根目录
tsconfig.json(或通过命令行指定),获取编译选项(如target目标 JS 版本、module模块规范、outDir输出目录等 )。 - 语法解析:将 TS 代码转换为抽象语法树(AST),同时进行类型检查,发现类型错误会抛出警告 / 报错(可配置
noEmitOnError决定是否停止编译)。 - 转译输出:根据
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)更主流 。