写了三年 TypeScript,我才搞懂类型到底写给谁看

刚学 TypeScript 的时候,我觉得类型就是给编译器看的——能跑就行,报错就加个 any 糊弄过去。

后来越写越觉得不对劲。直到有一次,一段三个月前写的代码出了 bug,我盯着屏幕看了十分钟,才发现自己根本看不懂当时在写什么。

从那以后,我对类型的看法完全变了。

any 的诱惑

any 特别好用。它说「这个东西随便是什么」,编译器就不吵你了。

问题是:你今天图省事写了 any,三个月后回头看,那个变量到底是个对象还是数组,全得靠猜。类型一丢,编辑器里的自动补全、跳转定义、改名重构,全都没了。

我不是说永远不能用 any。有时候第三方库的类型就是一团糟,你又急着上线,用一下没问题。但把它当默认选项,代码会悄悄烂掉。

strict 模式:一开始嫌烦,后来真香

strict 模式打开后,TS 会管得特别宽:可能为 undefined 的变量、没初始化的属性、乱来的 this……刚开始觉得它天天找茬。

但我后来发现一个规律:它拦住的全是真 bug。 那些红波浪线,上线之后基本都会变成用户手里的报错。现在新项目我第一件事就是把 strict 打开。

一个超实用的小模式

以前我特别爱用「魔法字符串」:

// 千万别这样
if (user.role === "admin") { ... }
if (user.role === "guest") { ... }

拼错一个字母,编译器一声不吭,运行时直接翻车。

换成联合类型之后:

type Role = "admin" | "guest" | "member";

function greet(role: Role) {
  // 这里只能写那三个值,写错立刻报错
}

拼错?编译器当场指出来。这种「把可能的值列出来」的思路,比任何注释都管用。

别拿类型炫技

我曾经特得意地写了个超复杂的条件类型,十行代码,能根据入参自动推断出返回值类型。看着很厉害。

然后同事(和我自己)读完一脸懵。最后我还是把它删了,换成二十行大白话的联合类型——可读性好了十倍,性能也没差哪去。

类型不是用来证明你多厉害的。它是写给半年后的你,让他还能看懂这段代码。

小结

  • any 是止痛药,不是饭,别当主食吃;
  • strict 模式拦住的都是真 bug,早点开;
  • 用联合类型代替魔法字符串,拼错当场报错;
  • 类型炫技一时爽,维护火葬场。

把类型当成像是「给未来的自己留的便签」,心态一下子就对了。