Menu

TypeScript 是什么?TypeScript 入门教程与示例

TypeScript 就是带静态类型的 JavaScript。你给值加上类型注解,编译器在代码运行前检查它们,最终输出的是普通 JavaScript,可以在任何浏览器以及 Node.js、Deno 和 Bun 中运行。

本页包含可运行的编辑器。编辑、运行,立即查看输出。

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

这里有两项独立的工作,由不同的工具完成:

  1. 类型检查。 只有 TypeScript 编译器能做这件事,通常是 tsc 命令(Deno 的 deno check 运行的也是同一个编译器)。它读取你的 .ts 文件,报告错误,默认还会写出 .js 文件。
  2. 去掉类型。 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 在程序运行时无法察觉。请用运行时代码(例如类型守卫)来验证这类数据。

Coddy 编程语言插图

和 Coddy 一起学编程

开始