TypeScript 就是带静态类型的 JavaScript。你给变量、参数和返回值加上类型注解,TypeScript 编译器在程序运行前检查它们,然后输出去掉了类型的普通 JavaScript。这些 JavaScript 能在任何支持 JavaScript 的地方运行:浏览器、Node.js、Deno 和 Bun。
下面是一个小小的 TypeScript 程序。点击“运行”。
输出:
Ada is 36 years old
82.33333333333333
除了冒号后面的部分(: string、: User、: number[])和 interface,这段代码就是 JavaScript。这些新增的部分告诉编译器每个值允许是什么。注意 total 没有注解:TypeScript 自己推断出它是一个数字。大多数 TypeScript 代码只在函数边界写注解,其余交给编译器推断。
类型检查器能发现什么
注解的意义在于,错误会在你写代码时就暴露出来,而不是等到用户碰上。运行这个代码块,看看输出:
程序根本不会启动。编译器会打印两个错误:
index.ts(11,38): error TS2322: Type 'string' is not assignable to type 'number'.
index.ts(12,22): error TS2741: Property 'age' is missing in type '{ name: string; }' but required in type 'User'.
每个错误都写明了文件、行号和列号、错误代码(TS2322)以及问题所在。如果是普通的 JavaScript,这两行都会运行,第二行会毫无警告地打印出 Linus is undefined years old。在 VS Code 这样的编辑器里,你一边输入,这些错误就会以红色波浪线显示出来,自动补全也知道 user 恰好有 name 和 age 两个属性。
类型检查器常能发现的 bug:
- 属性名或方法名拼写错误(
user.nmae、list.lenght)。 - 调用函数时参数太少或太多,或者参数类型不对。
- 使用一个可能是
null或undefined的值,却没有先检查。 - 代码使用了穷尽性检查时,漏掉了联合类型中的某一种情况,比如
"loading" | "done" | "error"。 - 你依赖的函数改了签名,导致调用它的代码出错。
类型在运行时会消失
TypeScript 的类型只存在于编译时。编译器检查完类型后就把它们去掉:生成的 JavaScript 里没有注解,也没有接口,运行起来和你手写的 JavaScript 完全一样。
这段输入:
function double(n: number): number {
return n * 2;
}
会变成这段输出:
function double(n) {
return n * 2;
}
所以 TypeScript 无法检查程序运行时才传进来的值。下面这段 JSON 文本声称自己是一个 User,编译器只能相信这个说法,运行时也不会有任何报错:
输出:
string
thirty-six1
来自程序外部的数据(API 响应、表单输入、文件)需要运行时检查,例如写一个检查值的类型守卫函数。TypeScript 会信任这个检查,并为你收窄类型。
TypeScript 是谁创造的,为什么要创造它
TypeScript 由微软创造,设计工作由 Anders Hejlsberg(C# 的设计者)主导。它于 2012 年 10 月以 0.8 版本公开发布,2014 年 4 月推出 1.0。它基于 Apache 2.0 许可证开源,在 GitHub 上开发。按 GitHub 统计的每月贡献者人数,TypeScript 在 2025 年 8 月成为 GitHub 上使用最多的语言,超过了 Python 和 JavaScript。
创造它的动机是大型 JavaScript 代码库。JavaScript 没有办法表达“这个函数接收一个用户对象”,所以重命名一个属性或修改一个函数,就意味着要搜索整个代码库,还得祈祷测试覆盖了每一个调用方。TypeScript 用一种完全兼容 JavaScript 的方式补上了这些信息:
- 它是超集。 合法的 JavaScript 就是合法的 TypeScript 语法,所以项目可以一次迁移一个文件。
- 它紧跟 JavaScript。 除了
enum和namespace等少数早期新增功能,TypeScript 不添加任何自己的运行时特性;新语法都来自 JavaScript 标准。 - 类型在运行时没有任何开销。 类型会被擦除,所以输出和手写的 JavaScript 一样快。
目前的主版本是 TypeScript 7,它的编译器用 Go 重写成了原生程序,检查大型项目类型的速度大约是被它取代的、基于 JavaScript 的编译器的十倍。TypeScript 7 页面介绍了具体有哪些变化。
TypeScript 用来做什么?前端和后端
TypeScript 能开发的软件和 JavaScript 一样,前端和后端都能用。因为输出的是 JavaScript,所以 JavaScript 能去的地方,TypeScript 都能去:
| 环境 | TypeScript 在那里怎么运行 |
|---|---|
| 浏览器前端 | 由构建工具(Vite、webpack、esbuild)编译成 JavaScript。React、Angular、Vue 和 Svelte 都支持它;Angular 项目默认就用 TypeScript。 |
| Node.js 服务器和脚本 | 用 tsc 编译后运行生成的 .js 文件,或者直接运行 .ts 文件:当前的 Node.js 版本会自己去掉类型。 |
| Deno | 直接运行 .ts 文件;用 deno check 做类型检查。 |
| Bun | 直接运行 .ts 文件,但不做类型检查。 |
| 桌面和移动端 | Electron、React Native 以及类似工具都支持 TypeScript。 |
同一种语言覆盖了 Web 应用的两端,所以很多团队会在服务器和浏览器代码之间共享类型定义(比如 API 响应的结构)。
TypeScript 代码如何变成 JavaScript
这里有两项独立的工作,由不同的工具完成:
- 类型检查。 只有 TypeScript 编译器能做这件事,通常是
tsc命令(Deno 的deno check运行的也是同一个编译器)。它读取你的.ts文件,报告错误,默认还会写出.js文件。 - 去掉类型。
tsc可以做,一些完全跳过类型检查、速度更快的工具也可以:esbuild、SWC、Babel,以及 Node.js、Deno 和 Bun 内置的类型剥离功能。
一种常见的做法是:用速度快的工具运行代码,在编辑器和 CI 中运行 tsc --noEmit(只检查,不写出任何文件)。安装 tsc 和运行 .ts 文件在本章中各有专门的页面。
一个例子看懂核心特性
日常的 TypeScript 只用到一小部分特性。下面这个代码块把主要的特性放在了一起:
输出:
Ada ada@example.com
Ada can log in
Linus is banned
- 类型注解(
name: string)说明变量、参数、属性或返回值存放的是什么。 - 类型推断会补上你省略的类型:
account的类型来自first的返回值。 - 接口和类型别名(
interface Account、type Status)为数据的结构命名。 - 联合类型(
"active" | "banned"、T | undefined)描述一个可能是几种情况之一的值。 - 类型收窄:经过
account !== undefined这样的检查后,编译器就知道代码块内是哪种情况。 - 可选属性(
email?: string)可以不存在,所以它的类型包含undefined。 - 泛型(
first<T>)让一个函数或类型能处理多种类型,同时保持类型之间的关联:传入Account数组,返回一个Account。
需要先学 JavaScript 吗?
先学会有帮助,但你也可以两个一起学。TypeScript 代码在运行时的一切行为(变量、函数、对象、数组、Promise、类)都属于 JavaScript,TypeScript 只是加了一层描述这些值的类型。如果你已经会 JavaScript,新内容就是类型系统:注解、接口、联合类型、泛型和类型收窄。如果两者都是新手,先学 JavaScript 的值和函数基础,再边学边加类型;编译器的错误信息是很好的老师,因为它会指出值被用错的那一行。
学习 TypeScript 的一个实用顺序:先安装它并运行第一个文件,学习基本类型和对象类型,然后学习联合类型和类型收窄,之后再学函数和泛型。这些就能覆盖大部分应用代码。
常见问题
简单来说,TypeScript 是什么?
TypeScript 是带类型注解的 JavaScript。你写下 let count: number = 0,编译器就会检查 count 是否始终被当作数字使用。之后编译器去掉这些注解,输出普通的 JavaScript,所以任何能运行 JavaScript 的环境都能运行编译结果。
TypeScript 是前端还是后端?
两者都是。TypeScript 会编译成 JavaScript,所以 JavaScript 能用在哪里,它就能用在哪里:浏览器前端(React、Angular、Vue、Svelte)、运行在 Node.js、Deno 或 Bun 上的服务器、命令行工具,以及用 Electron 构建的桌面应用。类型检查在这些场景中的效果都一样。
TypeScript 是编程语言还是框架?
是编程语言。它是 JavaScript 的超集:每个 JavaScript 程序都是合法的 TypeScript 语法,TypeScript 在此之上加了一套类型系统。它不是框架,也不是库:类型注解在编译时就会被移除,不会给你的程序增加任何代码。
TypeScript 是谁创造的?
微软(Microsoft)。设计工作由 Anders Hejlsberg 主导,他也是 C# 的设计者。TypeScript 于 2012 年 10 月以 0.8 版本公开发布,基于 Apache 2.0 许可证开源。
TypeScript 会在运行时检查类型吗?
不会。所有类型检查都发生在编译时,类型会从输出的 JavaScript 中擦除。如果来自程序外部的数据(API 响应、表单、JSON 文件)结构不对,TypeScript 在程序运行时无法察觉。请用运行时代码(例如类型守卫)来验证这类数据。