Skip to content

TypeScript 入门到实战(一):破冰之旅 —— 为什么你的下一个项目应该用 TypeScript?

你好,JavaScript 开发者!

你是否也曾在某个深夜,面对浏览器控制台里那个鲜红的 Uncaught TypeError: Cannot read properties of undefined (reading '...') 陷入沉思?或者在接手一个没有文档的旧项目时,对着一个巨大的 options 对象,苦苦猜测里面到底有哪些属性?

如果这些场景让你感同身受,那么恭喜你,这篇文章就是为你准备的。我们将开启一个全新的系列——"TypeScript 入门到实战",专门写给像你一样已经熟悉 JavaScript 的开发者。

我们的目标不是推翻你已有的知识,而是为你手中强大的 JavaScript"宝剑"装上一个精准的"瞄准镜"。这个瞄准镜,就是 TypeScript。

1. 直面 JavaScript 的"痛点"

在赞美 TypeScript 之前,我们先来回顾一下那些让我们又爱又恨的 JavaScript 特性——它的动态性和灵活性。这份灵活性在小型项目和快速原型开发中是优点,但随着项目规模的扩大,它常常会变成"陷阱"的温床。

场景一:致命的 undefined

这是最经典的错误。一个函数期望接收一个对象,但由于某种原因,你传了个 undefined

javascript
// a.js
function getUsername(user) {
  return user.name; // 如果 user 是 undefined, 这里就会在运行时爆炸!
}

// 运行时...
getUsername({ name: "Alice" }); // -> "Alice"
getUsername(undefined); // -> 💥 Uncaught TypeError: Cannot read properties of undefined (reading 'name')

场景二:模糊的函数签名

一个函数需要三个参数,但你不小心只传了两个,或者把顺序搞错了。JavaScript 不会阻止你,它只会默默地让 Bug 发生。

javascript
// utils.js
function createUser(name, age, email) {
  // ... 假设这里有复杂的逻辑
  console.log(`创建用户:${name}, 年龄:${age}, 邮箱: ${email}`);
}

// 几个月后,另一位同事在使用...
createUser("Bob", "bob@example.com"); // 忘了传 age
// 输出: 创建用户:Bob, 年龄:bob@example.com, 邮箱: undefined
// age 变成了邮箱,email 是 undefined,逻辑可能已经完全错误!

场景三:深不可测的对象

当你使用一个来自第三方库或历史代码的配置对象时,你只能靠查文档或 console.log 来探索它的结构。

javascript
// config.js
const complexOptions = {
  // ...里面有 20 个属性
  // a: 1, b: "hello", c: { d: true, ... }
};

function initialize(options) {
  // 我怎么知道 options 里有什么?
  // options.timeout 和 options.timeOut 哪个是正确的?
  // VSCode 也帮不了我太多。
}

这些问题都指向同一个根源:JavaScript 是动态类型语言,它只在代码运行时才进行类型检查。

2. TypeScript 是什么?—— 给 JavaScript 穿上"盔甲"

现在,主角登场。

核心定义: TypeScript 是 JavaScript 的一个超集(Superset),它为 JavaScript 添加了静态类型系统。

让我们拆解一下这句话:

  • 超集(Superset): 这意味着任何合法的 JavaScript 代码都是合法的 TypeScript 代码。你可以把一个 .js 文件直接改名为 .ts,它就能运行。这使得我们可以逐步、平滑地从 JS 迁移到 TS,而不是一场颠覆性的革命。
  • 静态类型: 这是 TS 的灵魂。与 JS 在运行时才检查类型不同,TS 在**代码编写阶段(编译前)**就会检查类型。

它的工作流程是这样的:

[你编写的 .ts 代码]  ->  [TypeScript 编译器 (tsc)]  ->  [纯净的、兼容性好的 .js 代码]
      (带类型)                 (类型检查、报错)                (不带类型)

关键点: 浏览器、Node.js 等任何 JavaScript 环境都不直接运行 TypeScript 代码。它们运行的是 TS 编译后生成的 JS 代码。TypeScript 只存在于我们的开发阶段,像一个严格的教练,确保我们上场比赛(运行时)前不出错。

3. TS 带来的核心优势

那么,多了一个编译步骤,换来了什么好处?

  1. 代码可读性和可维护性更高: 类型本身就是最好的文档。当你看到一个函数签名 function getUserById(id: number): User,你立刻就能明白它的作用,无需阅读内部实现。
  2. 在编码阶段发现错误: 这可能是最直观的感受。当你使用 VSCode 等现代编辑器时,如果你尝试将一个数字赋值给一个字符串变量,或者调用一个不存在的函数,你立刻就会看到红色的波浪线和清晰的错误提示。它将大量的运行时错误(Runtime Errors)提前扼杀在了开发阶段(Compile-time Errors)。
  3. 重构的信心来源: 想象一下,你要修改一个被项目十几个地方用到的函数,比如把 createUserage 参数从 number 改成 string。在 JS 中,你只能心惊胆战地全局搜索,祈祷不要漏掉任何一处。而在 TS 中,你只需要修改函数的类型定义,编译器就会像一个忠诚的助手,精确地告诉你所有需要修改的地方。
  4. 更好的团队协作: 类型定义就像团队成员之间的一份"契约"。interfacetype 清晰地定义了数据结构和 API 接口,大大减少了因沟通不畅导致的集成问题。

4. 你的第一个 TypeScript 程序

说了这么多,让我们动手实践一下。

第一步:安装 TypeScript

打开你的终端,运行以下命令来全局安装 TypeScript 编译器。

bash
npm install -g typescript

第二步:编写你的 TS 代码

创建一个新文件,命名为 hello.ts,然后输入以下代码:

typescript
function greet(person: string, date: Date) {
  console.log(`Hello ${person}, today is ${date.toDateString()}!`);
}

greet("Brendan Eich", new Date());

注意,我们为 person 参数指定了 string 类型,为 date 参数指定了 Date 类型。

第三步:编译和运行

在终端里,进入 hello.ts 所在的目录,然后运行:

bash
tsc hello.ts

命令执行后,你会发现目录里多出了一个 hello.js 文件,它的内容是:

javascript
// hello.js (编译后的产物)
function greet(person, date) {
    console.log("Hello ".concat(person, ", today is ").concat(date.toDateString(), "!"));
}
greet("Brendan Eich", new Date());

看到吗?类型注解消失了,TS 把它编译成了纯净、兼容的 JavaScript!

现在,你可以像往常一样用 Node.js 运行它:

bash
node hello.js
// 输出: Hello Brendan Eich, today is Tue Jul 01 2025! (日期会是当前日期)

第四步:初始化 TS 项目 (tsconfig.json)

在实际项目中,我们不会一个一个地手动编译文件。我们需要一个配置文件来告诉 TypeScript 编译器如何工作。这个文件就是 tsconfig.json

在你的项目根目录下运行:

bash
tsc --init

这会生成一个包含大量选项的 tsconfig.json 文件。别被它吓到,在初期,我们只需要关注几个核心选项:

  • "target": 指定编译后生成的 JavaScript 版本。例如,"ES2016" 是一个很安全的选择,兼容性好。
  • "module": 指定使用哪种模块系统。对于 Node.js 项目,通常是 "CommonJS";对于现代前端项目,可能是 "ES2020""ESNext"
  • "strict": 强烈建议保持 true 这是一个"严格模式"的开关,它会开启一系列类型检查规则,帮助你写出更健壮的代码。

总结与展望

今天,我们踏出了从 JavaScript 到 TypeScript 的第一步。我们理解了 TS 并非一种全新的语言,而是 JS 的增强版,它通过静态类型系统解决了 JS 在大型项目中常见的痛点。

你已经成功地编写并编译了你的第一个 TypeScript 程序,并了解了 tsconfig.json 的基本作用。

核心 takeaway: TypeScript 让你能够用写 JavaScript 的方式,享受静态类型语言带来的安全性和可维护性。

在下一篇文章**《TypeScript 入门到实战(二):基础武器库 —— 掌握 TS 核心类型与函数》**中,我们将深入探索 TypeScript 提供的各种基础类型,学习如何为变量、函数和数据结构添加准确的类型定义。

敬请期待!