第 1 卷
TypeScript 与 JavaScript 的核心差异解析
- TypeScript 与 JavaScript 的主要区别是什么?
你想了解的核心是 TS 和 JS 的核心差异,本质上 TypeScript 是 JavaScript 的超集(Superset),核心区别可总结为以下几点:
| 维度 | TypeScript | JavaScript |
|---|---|---|
| 类型系统 | 静态类型(编译时检查),支 | 动态类型(运行时检查),无 |
| 持显式类型标注 | 类型约束 | |
| 语言特性 | 支持接口、泛型、枚举、高级 | 仅原生 ES 特性,无上述扩展 |
类型等扩展特性
编译过程需编译为 JS 才能运行(TSC 直接在浏览器/Node 环境运行编译器)
| 错误检测 | 编译阶段发现类型错误,提前 | 运行阶段才暴露错误,调试成 |
|---|---|---|
| 规避问题 | 本高 | |
| 生态兼容 | 完全兼容 JS,可渐进式接入 | 原生语言,无兼容成本 |
| 使用场景 | 大型项目、团队协作、复杂业 | 小型脚本、快速原型开发 |
务逻辑
核心优势:TS 的静态类型能提升代码可维护性、可读性,降低团队协作的沟通成本,尤其适合中大型前端项目。
2. 接口 (Interfaces) 和类型别名 (Type Aliases) 的异同
相同点
- 都能用来描述对象/函数的形状,实现类型约束;
- 都支持扩展(接口用 extends,类型别名用交叉类型 &);
- 都支持可选属性、只读属性、函数类型定义。
不同点
扩展方式支持多次声明自动合并(接口不支持合并,重复声明会报错合并)
| 适用场景 | 主要描述对象/类的结构(面 | 可描述任意类型(基本类型、 |
|---|---|---|
| 向对象) | 联合类型、元组等) | |
| 计算属性 | 不支持 | 支持(如 type Obj = { |
[key: string]: number })
类实现类可通过 implements 实现类无法实现类型别名(除非是接口对象类型)
示例对比:
Code block
1// 接口(支持合并)
2interface User { 3name: string;
4} 5interface User {
6age: number; // 自动合并,最终 User = { name: string; age: number } 7}
8 9// 类型别名(不支持合并)
10type User = { name: string };
11// type User = { age: number }; // 报错:标识符“User”重复 12
13// 类型别名支持基本类型,接口不行 14type Str = string; // 合法
15// interface Str = string; // 报错
使用建议:描述对象/类的结构优先用接口;需要描述基本类型、联合类型、元组等用类型别名。
3. 泛型 (Generics) 是什么?使用示例
泛型是 TS 的核心特性,允许定义“可复用、类型可参数化”的代码,解决“类型固定导致复用性差”的问题,核心是“类型变量”(类似函数的参数)。
- 让函数/类/接口支持多种类型,同时保留类型检查;
- 避免重复定义多个类型版本的函数/类。
基础示例(泛型函数)
Code block
1// 泛型函数:返回与输入相同类型的值 2function identity<T>(arg: T): T {
3return arg;
4} 5
6// 使用:指定类型 7const str = identity<string>("hello"); // str 类型为 string
8const num = identity<number>(123); // num 类型为 number 9
10// 自动推断类型(更常用)
11const bool = identity(true); // bool 类型为 boolean
进阶示例(泛型接口 + 泛型类)
Code block
1// 泛型接口:描述数组包装器 2interface ArrayWrapper<T> {
3data: T[];
4add: (item: T) => void;
5} 6
7// 泛型类:实现上述接口
| 8 | class NumberWrapper implements ArrayWrapper<number> { |
|---|---|
| 9 | data: number[] = []; |
| 10 | add(item: number) { |
| 11 | this.data.push(item); |
| 12 | } |
| 13 | } |
14 15const wrapper = new NumberWrapper();
16wrapper.add(1); // 合法 17// wrapper.add("1"); // 报错:类型“string”的参数不能赋给类型“number”的参数