前置知识: JavaScript

TypeScript 概述与环境配置

14 min入门

TypeScript 发展历程、与 JavaScript 的关系与开发环境搭建。

前置知识

学习目标

  • 掌握「1. TypeScript 概述 (Overview)」的核心机制、典型用法与常见陷阱
  • 掌握「2. 环境配置 (Environment Setup)」的核心机制、典型用法与常见陷阱
  • 掌握「3. tsconfig.json 核心配置」的核心机制、典型用法与常见陷阱
  • 掌握「4. 工具链与生态系统」的核心机制、典型用法与常见陷阱
  • 掌握「5. 最佳实践」的核心机制、典型用法与常见陷阱

1. TypeScript 概述 (Overview)

TypeScript 是 JavaScript 的一个超集,由微软开发,于 2012 年首次发布。它在 JavaScript 的基础上增加了静态类型系统和其他高级特性,最终通过编译器转换为纯 JavaScript 代码运行。TypeScript 的设计目标是帮助开发者构建大型、复杂的应用程序,提供更好的开发体验和代码质量。

1.1 核心价值 (Core Value)

价值描述优势
类型安全在开发阶段发现潜在错误 (如拼写错误、类型不匹配)减少运行时错误,提高代码可靠性
更好的 IDE 支持自动补全、重构更精准,提供更好的代码导航提高开发效率,减少编码错误
增强可读性类型注解使代码更加自文档化便于团队协作和代码维护
支持最新语法提前使用尚未在所有浏览器实现的 ECMAScript 新特性保持代码现代化,无需等待浏览器支持
渐进式 adoption可以与 JavaScript 代码无缝集成便于现有项目逐步迁移到 TypeScript
大型项目支持提供模块化、命名空间等特性适合构建和维护大型应用程序

1.2 TypeScript 与 JavaScript 的关系

TypeScript 是 JavaScript 的超集,这意味着:

  • 所有 JavaScript 代码都是有效的 TypeScript 代码
  • TypeScript 增加了额外的特性,如类型注解、接口、泛型等
  • TypeScript 代码最终会被编译为 JavaScript 代码运行
  • TypeScript 可以与 JavaScript 代码和库无缝集成

1.4 应用场景

TypeScript 适用于以下场景:

  • 大型应用程序:需要类型安全和更好的代码组织
  • 团队开发:需要清晰的代码结构和类型约束
  • 前端框架:React、Vue、Angular 等框架的类型定义
  • Node.js 后端:提供类型安全的服务器端代码
  • 库和工具:提供类型定义,改善开发者体验

2. 环境配置 (Environment Setup)

2.1 安装 TypeScript

2.1.1 全局安装

bash
 # 全局安装 TypeScript 编译器
 npm install -g typescript
 # 验证安装
 tsc --version

讲解:

  1. npm install -g 把 TypeScript 安装到全局,之后任何目录都能直接用 tsc 命令。
  2. tsc --version 验证安装是否成功,并显示当前版本号。
  3. 全局安装适合学习阶段;真实项目应使用下面的”本地安装”,保证团队版本一致。

2.1.2 项目本地安装

bash
 # 在项目中本地安装 TypeScript
 npm install --save-dev typescript
 # 验证安装
 npx tsc --version

讲解:

  1. --save-dev 表示 TypeScript 是开发依赖:只在开发与构建时使用,不会进入生产代码。
  2. 本地安装后不能直接敲 tsc,要写 npx tsc——npx 会优先使用项目里的 node_modules/.bin/tsc。
  3. 团队项目必须用本地安装:每个人执行 npm install 后得到完全相同的编译器版本。

2.2 初始化 TypeScript 项目

2.2.1 生成 tsconfig.json

bash
 # 生成默认的 tsconfig.json 文件
 tsc --init
 # 或使用 npm init 初始化项目后添加 TypeScript
 npm init -y
 npm install --save-dev typescript
 npx tsc --init

讲解:

  1. tsc --init 生成带注释的 tsconfig.json,里面包含 TypeScript 全部配置项的说明。
  2. 第二组命令是标准三步:npm init -y 生成 package.json,安装 TypeScript,再初始化编译配置。
  3. tsconfig.json 是项目的”编译说明书”,后面的 3.x 小节会逐项解释。

2.2.2 基本项目结构

my-project/

tsconfig.json # TypeScript 配置文件

package.json # 项目配置文件

src/ # 源码目录

index.ts # 主入口文件

dist/ # 编译输出目录

index.js # 编译后的 JavaScript 文件

my-project/

tsconfig.json # TypeScript 配置文件

package.json # 项目配置文件

src/ # 源码目录

index.ts # 主入口文件

dist/ # 编译输出目录

index.js # 编译后的 JavaScript 文件

mermaid diagram

结构解析:

  1. 图中只有两条路径需要记住:源码在 src/,编译产物在 dist/。
  2. tsconfig.json 决定”从 src 编译到 dist”,package.json 记录依赖与脚本。
  3. index.ts 是入口文件,编译后变成同名的 index.js,交给 Node.js 或浏览器运行。

2.3 编译与运行

2.3.1 基本编译

bash
 # 编译单个文件
 tsc src/index.ts
 # 编译整个项目 (使用 tsconfig.json)
 tsc
 # 监视模式编译 (文件变化时自动重新编译)
 tsc --watch

讲解:

  1. tsc src/index.ts 只编译指定文件;tsc(不带参数)按 tsconfig.json 编译整个项目。
  2. --watch 是”监听模式”:保存文件后自动重新编译,开发时一直开着即可。
  3. 初学者最常用的组合是:一个终端跑 tsc --watch,编辑器里直接看类型报错。

2.3.2 使用 ts-node 直接运行

bash
 # 安装 ts-node
 npm install --save-dev ts-node
 # 直接运行 TypeScript 文件
 npx ts-node src/index.ts
 # 监视模式运行
 npx ts-node --watch src/index.ts

讲解:

  1. ts-node 在内存里把 TypeScript 编译后直接执行,省去”先编译再看 js”的步骤。
  2. npx ts-node src/index.ts 与 node dist/index.js 效果相同,但能更快进入调试。
  3. 注意:ts-node 只适合开发;生产环境一般用 tsc 编译出 JS 后再运行。
  4. 2026 年的新项目更推荐 tsx(基于 esbuild,更快、零配置):npm install --save-dev tsx 后用 npx tsx src/index.ts。ts-node 已进入维护模式,遇到新项目优先选 tsx。另外 Node.js 22.6+ 的原生「类型剥离」也能直接跑部分 TS 文件,详见 typescript/680-TypeScript6And7CompilerEvolution。

2.3.3 使用构建工具

脚本直跑(上一节的 ts-node/tsx)适合小项目;进入工程化阶段后,构建工具要同时负责编译、打包与开发服务器(HMR)三件事。下面给出使用最广的两种:Webpack(全功能、配置重)与 Vite(开发期按需编译、启动快)。

Webpack

bash
 # 安装依赖
 npm install --save-dev webpack webpack-cli ts-loader
 # webpack.config.js
 module.exports = {
  entry: './src/index.ts',
  module: {
  rules: [
  {
  test: /\.tsx?$/,
  use: 'ts-loader',
  exclude: /node_modules/
  }
  ]
  },
  resolve: {
  extensions: ['.tsx', '.ts', '.js']
  },
  output: {
  filename: 'bundle.js',
  path: path.resolve(__dirname, 'dist')
  }
 }

讲解:

  1. 这是 Webpack 的最小 TS 配置:entry 是入口文件,output 是打包结果。
  2. module.rules 里的 ts-loader 负责把 .tsx? 文件编译成 JS,exclude: /node_modules/ 跳过第三方库。
  3. resolve.extensions 让 import 时可以省略 .ts/.tsx/.js 后缀。
  4. 新项目更推荐 Vite(下一段),Webpack 主要用于维护存量项目。

Vite

bash
 # 创建 Vite + TypeScript 项目
 npm create vite@latest my-project -- --template react-ts
 # 或使用 Vue + TypeScript
 npm create vite@latest my-project -- --template vue-ts

讲解:

  1. npm create vite@latest 是官方脚手架:--template react-ts 生成 React+TS 模板,vue-ts 生成 Vue+TS 模板。
  2. 创建后进入目录执行 npm install && npm run dev 即可启动。
  3. Vue 项目也可用官方 create-vue,在交互提示中勾选 TypeScript 支持。

创建 Vue + TypeScript 项目更推荐官方脚手架 create-vue:npm create vue@latest,在交互提示中选择 TypeScript。

本篇 v2 起做了两处拆分:3. tsconfig.json 核心配置 一节整体并入 TypeScript 工程化配置(作为其第 3 节速成篇);文末 TS 5.x 新特性速查(const 类型参数、satisfies、using、switch(true)、NoInfer、推断谓词、import defer 等共 12 节)整体并入 TypeScript 5.x 新特性演进 对应年份章节。本篇保留 TypeScript 概述、环境配置与工具链生态主线。

3. 工具链与生态系统

3.1 开发工具

工具描述用途
tscTypeScript 编译器编译 TypeScript 代码
ts-node直接运行 TypeScript 文件开发和调试
tslint/eslintTypeScript 代码检查工具代码质量检查
prettier代码格式化工具保持代码风格一致
jest测试框架单元测试
webpack模块打包工具前端项目构建
vite现代前端构建工具快速开发和构建
rollup模块打包工具库构建

3.2 类型定义

类型定义描述安装方式
@types/nodeNode.js 类型定义npm install --save-dev @types/node
@types/reactReact 类型定义npm install --save-dev @types/react
@types/react-domReact DOM 类型定义npm install --save-dev @types/react-dom
@types/jestJest 类型定义npm install --save-dev @types/jest
*@typescript-eslint/ESLint TypeScript 插件npm install --save-dev @typescript-eslint/eslint-plugin @typescript-eslint/parser

3.3 IDE 支持

推荐的 IDE 和编辑器:

IDE/编辑器特点推荐插件
Visual Studio Code官方推荐,内置 TypeScript 支持TypeScript Hero, ESLint, Prettier
WebStorm强大的 IDE,内置 TypeScript 支持ESLint, Prettier
Sublime Text轻量级编辑器TypeScript, SublimeLinter
Atom开源编辑器atom-typescript

4. 最佳实践

4.1 项目结构

my-project/

tsconfig.json # TypeScript 配置

package.json # 项目配置

.eslintrc.json # ESLint 配置

.prettierrc # Prettier 配置

src/ # 源码目录

index.ts # 主入口

components/ # 组件

utils/ # 工具函数

types/ # 类型定义

interfaces/ # 接口定义

dist/ # 编译输出

tests/ # 测试文件

my-project/

tsconfig.json # TypeScript 配置

package.json # 项目配置

.eslintrc.json # ESLint 配置

.prettierrc # Prettier 配置

src/ # 源码目录

index.ts # 主入口

components/ # 组件

utils/ # 工具函数

types/ # 类型定义

interfaces/ # 接口定义

dist/ # 编译输出

tests/ # 测试文件

mermaid diagram

结构解析:

  1. 源码目录按”组件/工具/类型/接口”分包,是中型项目的常见组织方式。
  2. types/ 与 interfaces/ 集中放类型定义,避免类型散落在业务文件里。
  3. tests/ 与源码分开,便于测试工具按目录扫描。

4.2 类型定义最佳实践

  • 使用接口定义对象结构:清晰描述对象的形状
  • 使用类型别名:为复杂类型创建有意义的名称
  • 避免使用 any 类型:尽量使用具体类型或联合类型
  • 使用泛型:提高代码复用性和类型安全性
  • 使用枚举:为一组相关常量提供有意义的名称
  • 使用命名空间:组织相关类型和功能

4.3 代码风格

  • 使用 PascalCase:命名类、接口、类型别名
  • 使用 camelCase:命名函数、变量、属性
  • 使用 UPPER_SNAKE_CASE:命名常量
  • 使用下划线前缀:命名私有成员
  • 使用 JSDoc 注释:为类型和函数添加文档

4.4 性能优化

  • 使用类型断言:在确知类型时使用,避免不必要的类型检查
  • 使用 const 断言:为字面量类型提供更精确的类型
  • 使用类型守卫:在运行时检查类型
  • 避免过度泛型:只在必要时使用泛型
  • 使用模块导入:避免全局命名空间污染

5. 实际应用示例

5.1 基本 TypeScript 示例

typescript
 // src/index.ts
 // 类型定义
 interface User {
  id: number;
  name: string;
  email: string;
  age?: number; // 可选属性
 }
 // 函数定义
 function greet(user: User): string {
  return `Hello, ${user.name}!`;
 }
 // 类定义
 class UserService {
  private users: User[] = [];
  addUser(user: User): void {
  this.users.push(user);
  }
  getUserById(id: number): User | undefined {
  return this.users.find(user => user.id === id);
  }
  getAllUsers(): User[] {
  return this.users;
  }
 }
 // 使用示例
 const userService = new UserService();
 userService.addUser({
  id: 1,
  name: "John Doe",
  email: "john@example.com",
  age: 30
 });
 userService.addUser({
  id: 2,
  name: "Jane Smith",
  email: "jane@example.com"
 });
 const user = userService.getUserById(1);
 if (user) {
  console.log(greet(user));
 }
 console.log(userService.getAllUsers());

讲解:

  1. interface User 定义对象形状:age?: number 表示 age 可省略,这就是”可选属性”。
  2. function greet(user: User): string 标注参数类型与返回值类型,传错结构会在编译期报错。
  3. class UserService 中 private users: User[] 是私有数组字段;User | undefined 表示”可能找不到”。
  4. find 可能返回 undefined,所以用 if (user) 判断后再调用——strictNullChecks 强制处理这个分支。
  5. 最后 console.log(greet(user)) 输出带模板字符串的问候语,getAllUsers() 打印完整列表。

5.2 编译与运行

bash
 # 编译
 tsc
 # 运行
 node dist/index.js
 # 或直接运行
 npx ts-node src/index.ts

讲解:

  1. tsc 先按配置把 src/ 编译到 dist/,再 node dist/index.js 运行编译结果。
  2. 开发调试用 npx ts-node src/index.ts 更省事,一条命令完成”编译+运行”。
  3. 生产部署应使用 tsc 的编译产物,运行环境不需要安装 TypeScript。

5.3 与 JavaScript 集成

typescript
// src/index.ts
// 导入 JavaScript 模块
import { calculateTotal } from './utils.js';
// 类型定义
interface Order {
  id: number;
  items: {
    name: string;
    price: number;
    quantity: number;
  }[];
}
// 使用 JavaScript 函数
const order: Order = {
  id: 1,
  items: [
    { name: 'Item 1', price: 10, quantity: 2 },
    { name: 'Item 2', price: 15, quantity: 1 },
  ],
};
const total = calculateTotal(order.items);
console.log(`Order total: $${total}`);
// ---------- 下面是普通 JavaScript 文件 utils.js ----------
// src/utils.js
// JavaScript 函数
export function calculateTotal(items) {
  return items.reduce((total, item) => {
    return total + item.price * item.quantity;
  }, 0);
}

讲解:

  1. 前半段是 TypeScript 调用 JavaScript:import { calculateTotal } from './utils.js' 导入 JS 模块,并给订单数据标注 Order 类型。
  2. items 的类型是”对象数组”:{ name: string; price: number; quantity: number }[],数组里每个元素结构一致。
  3. 后半段 utils.js 是普通 JS:reduce 累加 price * quantity。TypeScript 项目可以逐步把 JS 文件改成 TS,不用一次性重写。
  4. 这是”渐进式迁移”的样板:JS 函数保持不动,调用方先获得类型。

6. 常见问题与解决方案

6.1 编译错误

错误原因解决方案
Type ‘X’ is not assignable to type ‘Y’类型不匹配检查变量类型,确保类型一致
Property ‘X’ does not exist on type ‘Y’属性不存在检查对象结构,确保属性存在或使用可选属性
Cannot find name ‘X’变量未定义检查变量是否已声明,或添加类型定义
Module ‘X’ has no exported member ‘Y’模块导出不存在检查模块导出,确保导出名称正确
Cannot find module ‘X’模块未找到检查模块路径,确保模块已安装

6.2 类型定义问题

问题原因解决方案
缺少类型定义第三方库没有类型定义安装 @types/ 包或创建自定义类型定义
类型冲突多个类型定义冲突检查类型定义文件,解决冲突
类型过于严格类型定义过于严格使用类型断言或调整类型定义
类型不完整类型定义不完整扩展类型定义或使用接口继承

6.3 性能问题

问题原因解决方案
编译速度慢项目过大或配置不当优化 tsconfig.json,使用增量编译
类型检查慢复杂类型或循环依赖简化类型定义,避免循环依赖
运行时性能编译输出效率低优化 TypeScript 代码,使用适当的编译选项

6.4 工具链问题

问题原因解决方案
与 Babel 集成配置冲突使用 @babel/preset-typescript
与 Webpack 集成配置不当正确配置 ts-loader 或 babel-loader
与 ESLint 集成规则冲突使用 @typescript-eslint/eslint-plugin
与 Prettier 集成格式冲突配置 Prettier 与 ESLint 配合

7. 学习资源

7.1 书籍

  • 《TypeScript 实战》 - 梁宵
  • 《深入理解 TypeScript》 - Basarat Ali Syed
  • 《TypeScript 编程》 - Boris Cherny
  • 《TypeScript 权威指南》 - 张容铭

7.3 在线教程

7.4 社区与论坛

8. 总结

TypeScript 是一种强大的编程语言,它通过添加静态类型系统和其他高级特性,使 JavaScript 开发更加安全、高效和可维护。通过正确配置环境、使用最佳实践和利用丰富的工具链,开发者可以充分发挥 TypeScript 的优势,构建高质量的应用程序。

8.1 关键要点

  • 类型安全: TypeScript 的核心价值在于提供静态类型检查,减少运行时错误
  • 渐进式 adoption: 可以与 JavaScript 无缝集成,便于现有项目逐步迁移
  • 强大的工具链: 丰富的工具和 IDE 支持,提高开发效率
  • 现代语言特性: 支持最新的 ECMAScript 特性,保持代码现代化
  • 大型项目支持: 适合构建和维护大型应用程序

8.2 学习建议

  • 从基础开始: 学习 TypeScript 的基本类型和语法
  • 实践项目: 通过实际项目练习 TypeScript
  • 阅读文档: 参考官方文档和最佳实践
  • 参与社区: 加入 TypeScript 社区,学习和分享经验
  • 持续学习: 关注 TypeScript 的更新和新特性 TypeScript 已经成为现代前端和 Node.js 开发的重要工具,掌握 TypeScript 可以帮助开发者构建更加可靠、可维护的应用程序,提高开发效率和代码质量。

附录:核心术语表(零基础速查)

本表收录零基础前三周必然遇到的术语,一句话解释,不追求学术严谨,只求可理解。遇到陌生词先来这里查。

术语一句话解释
类型(Type)数据的”种类”:数字、字符串、对象、数组等,决定能对它做什么操作
类型注解在变量/参数后写 : 类型 的语法,声明”这里必须是这个类型”
类型推断你不写注解时,编译器根据值自动猜出类型(能猜就不用手写)
接口(interface)描述对象”长什么样”的契约:有哪些字段、字段什么类型
类型别名(type)给一个类型起名字,方便复用;也能表达联合、元组等接口表达不了的类型
联合类型(Union)“或”:string | number 表示既可能是字符串也可能是数字
交叉类型(Intersection)“且”:A & B 表示同时满足 A 和 B 的全部字段
字面量类型把”值本身”当类型:"active" 表示只能等于这个字符串
泛型(Generic)占位类型 <T>:调用时再确定具体类型,让函数/类适配多种类型
类型守卫(Type Guard)用 typeof/instanceof 等判断在运行时”收窄”类型,让代码更安全
类型断言(as)告诉编译器”我知道它是什么类型”(有撒谎风险,能不用就不用)
条件类型类型层面的三目运算:T extends X ? A : B
协变/逆变高级类型兼容规则:数组是协变的、函数参数是逆变的,初学先记住”赋值时类型要兼容”
类型体操用条件类型、映射类型等”像写程序一样写类型”,属于进阶领域
速查(Cheat Sheet)文档末尾的紧凑代码片段区,用于查阅而非逐行精读