彻底掌握 TypeScript——快速搭建你的 TypeScript 开发环境

0 阅读7分钟

本章将带你快速浏览一遍 TypeScript 的核心基础,帮助你尽快上手。我们会先简要讨论 TypeScript 与 JavaScript 的不同之处;接着,从宏观层面对这门语言的工作方式做一个概览;最后,还会介绍开始使用 TypeScript 所需要的工具。

TypeScript 与 JavaScript 有什么不同?

TypeScript 与 JavaScript 的差异,其实可以用一个词来概括:类型(types) 。但这里存在一个常见误解。很多人以为 TypeScript 的核心使命,是把 JavaScript 变成像 C# 或 Rust 那样的强类型语言,但这并不完全准确。TypeScript 并不是为了把 JavaScript 变成强类型语言而发明的;它诞生的真正目的,是为了让 JavaScript 拥有强大的工具支持。

设想一下,你正在构建一个集成开发环境(IDE),并且想在用户把函数名或对象属性拼错时及时给出警告。如果你不知道代码中变量、参数和对象的“形状”是什么,那你就只能靠猜测来判断。但如果你知道应用中所有内容的类型,就能够开始实现强大的 IDE 能力,例如自动补全、内联报错以及自动重构。

TypeScript 的目标,就是提供恰到好处的强类型能力,让 JavaScript 的开发体验更加舒适,也更高效。

从宏观上看,TypeScript 是如何工作的

在一个纯 JavaScript 项目中,你通常会把代码写在扩展名为 .js 的文件里。这些文件随后可以被浏览器,或像 Node.js 这样的运行时环境直接执行(Node.js 用于在服务器或你自己的电脑上运行 JavaScript)。也就是说,你写下的 JavaScript,就是最终被执行的 JavaScript,如图 1-1 所示。

image.png

图 1-1:纯 JavaScript 工作流概览

如果你想验证代码是否可用,就必须在运行时里进行测试,也就是在浏览器或 Node.js 中测试。

而在 TypeScript 项目里,你的代码主要写在 .ts.tsx 文件中。在 IDE 中,这些文件会被 TypeScript 的**语言服务器(language server)**持续监控。这个服务器会在你输入代码的同时进行观察,并驱动 IDE 中的各种功能,例如自动补全、错误检查等等。

.js 文件不同,.ts 文件通常不能被浏览器或运行时直接执行。相反,它们需要先经过一个初始的构建过程。这时就轮到 TypeScript 的 tsc 命令行工具登场了。它会把你的 .ts 文件转换成 .js 文件。这意味着:你在编写代码时可以享受到 TypeScript 带来的各种能力,而最终输出的结果依然是普通的 JavaScript,如图 1-2 所示。

image.png

图 1-2:TypeScript 项目工作方式概览

这套机制的巨大优势在于,它让你进入了一个与 TypeScript 之间的反馈闭环:
你编写代码;IDE 内的服务器给出反馈;你根据反馈调整代码。并且,这一切都发生在代码进入浏览器之前。

在 JavaScript 中,你往往必须一路走到运行时阶段,才能发现某些缺陷。而 TypeScript 的反馈循环则完全发生在 IDE 内部,因此它能帮助你更快地写出质量更高的代码。

注意
自动化测试同样能够提供高质量的反馈闭环。虽然本书不会讨论自动化测试,但它与 TypeScript 搭配使用,是打造高质量代码的绝佳组合。

TypeScript 开发所需的工具

下面我们来拆解一下,使用 TypeScript 需要哪些工具。

IDE
要写代码,你需要一个编辑器或 IDE。虽然你可以使用任何 IDE,但本书默认你使用的是微软的 Visual Studio Code(VS Code)。正如你很快会看到的,TypeScript 与 VS Code 的集成体验非常出色。如果你还没有安装,可以前往 https://code.visualstudio.com/download 下载。它支持 Windows、macOS 和 Linux。

执行环境
你需要一个能够运行生成后的 JavaScript 的地方,比如 Node.js,或者像 Chrome 这样的 Web 浏览器。

TypeScript CLI
你还需要 Node.js 来运行 TypeScript 的命令行工具。这个工具会把你的 TypeScript 转换成 JavaScript,并在项目中存在问题时给出警告。

安装 Node.js

请从 https://nodejs.org 下载 Node.js 安装程序。访问网站后,你会看到两个选项:LTSCurrent

LTS 是 Long Term Support(长期支持版) 的缩写,也是推荐在生产环境中使用的版本。它同时也是最稳定的版本,并且本书将使用这一版本。Current 版本则包含最新特性,但并不推荐用于生产环境。

点击 LTS 按钮下载安装程序,然后按照安装说明完成安装。

安装完成后,你可以打开终端并运行以下命令,确认是否安装成功:

node -v

如果 Node.js 已正确安装,这条命令会显示版本号。
如果你看到类似 node command not found 这样的错误信息,就说明安装没有成功,需要重新尝试。

安装 pnpm 包管理器

为了运行本书中的练习,你还需要一个工具,用来安装一些第三方包。这里我们不会使用传统的 npm 包管理器,而是会使用一个叫做 pnpm 的工具。

Node.js 默认自带 npm 包管理器。如果你接触过 JavaScript 项目仓库,你大概率已经熟悉 npm 和 package.json 文件。package.json 文件描述了运行该仓库中的代码所需安装的全部包。

例如,在本书配套仓库中,我们定义了一个专门用于运行练习的 CLI,以及一些辅助包和其他依赖,比如 cross-fetchnodemon

// Inside package.json
{
  "devDependencies": {
    "@total-typescript/exercise-cli": "0.4.0",
    "@total-typescript/helpers": "~0.0.1",
    "cross-fetch": "~3.1.5",
    "nodemon": "~3.0.1",
    "npm-run-all": "~4.1.5",
    "prettier": "~2.8.7",
    "typescript": "~5.2.2",
    "vite-tsconfig-paths": "~4.0.7",
    "vitest": "0.34.4"
  }
}

要安装这些包,通常你会运行 npm install 命令,它会从 npm 仓库中把这些依赖下载到你的 node_modules 文件夹里。node_modules 文件夹中包含了 src 目录下练习代码运行所需的 JavaScript 文件。

不过,对于本书的仓库,我们将改用 pnpm 包管理器。它的工作方式与 npm 基本相同,但效率更高。pnpm 不会为每个项目单独创建一份 node_modules,而是会在你的电脑上使用一个统一的位置来存储依赖,再通过硬链接把依赖连接到各个项目中。这样一来,它运行更快,占用的磁盘空间也更少。我们在所有项目中都使用 pnpm。要安装 pnpm,请按照官方文档中的说明操作:https://pnpm.io/installation

安装完成后,你可以运行以下命令检查它是否正常工作:

pnpm --version

安装 TypeScript

TypeScript 及其依赖都包含在一个单独的包中,这个包就叫 typescript。你可以使用 npm 在系统中安装它:

npm install --global typescript

加上 --global 参数后,tsc 命令行工具会被全局安装到你的系统中。这样,你就可以在命令行中直接运行 tsc 来完成各种任务,例如创建 TypeScript 配置文件、检查代码等。

通常情况下,TypeScript 也会被安装到项目本地,以确保所有参与该项目的开发者都使用相同的版本。但对于本书的学习目的来说,全局安装已经完全足够。

小结

本章介绍了 TypeScript:它的首要目标并不是把 JavaScript 变成一门强类型语言,而是为 JavaScript 提供强大的工具支持。TypeScript 通过提供“恰到好处”的类型能力,使自动补全、内联报错等 IDE 特性成为可能,从而让开发过程更舒适、更高效。

与 JavaScript 不同,TypeScript 的开发流程是:你在 .ts 文件中编写代码,这些文件会被 TypeScript 的语言服务器实时监控并反馈信息;而在运行之前,这些文件必须通过 tsc CLI 编译为 .js 文件。这样就形成了一个完全发生在 IDE 内部的、更快速的反馈闭环。

要开始进行 TypeScript 开发,你需要一个 IDE(例如 VS Code)、一个执行环境(例如 Node.js 或浏览器),以及 TypeScript CLI。本章也具体演示了如何安装 Node.js(推荐使用 LTS 版本)、如何安装比 npm 更高效的 pnpm 包管理器,以及如何通过 npm 全局安装 TypeScript。

这套开发方式最大的优势在于:你可以在写代码的同时立即获得反馈,在代码进入运行时环境之前就发现并修复问题,最终写出更高质量的代码。