TypeScript 速查:常用类型语法与 TS 类型系统入门
从 interface、type、泛型、联合类型到工具类型 Partial 和 Pick,梳理 TypeScript 日常真用得上的类型写法,讲清和 JS 的区别,顺带拆几个新手最常踩的报错。
TypeScript 速查:常用类型语法与 TS 类型系统入门
我带过几个刚从 JavaScript 转过来的同事,发现卡住他们的不是语法本身,而是没人把「日常到底用哪几个写法」说清楚。TypeScript 文档很全,但真正撸代码时反复用到的就那么几类:接口和类型别名、泛型、联合类型、工具类型。这篇按这个顺序过一遍,每段都给能直接抄的代码。
TS 和 JS 的区别在哪
最直接的一句话:TypeScript 是给变量、函数参数、返回值标注类型的 JavaScript,编译时检查,运行时这些类型信息全部被擦掉。也就是说浏览器最后跑的还是普通 JS,类型只在你写代码、构建打包这两个阶段起作用。
好处很具体。下面这个函数在 JS 里传错参数要等运行时才发现:
function greet(name: string): string {
return `你好,${name}`;
}
greet(42); // 编译期就报错:Argument of type 'number' is not assignable to 'string'
错误在你敲下去那一刻编辑器就标红了,不用等跑起来。这就是 TS 最核心的价值:把一类运行时 bug 提前到编译期。
interface 和 type:描述对象形状
描述一个对象长什么样,有两种写法。interface 用来声明可被扩展、可被 class 实现的对象形状:
interface User {
name: string;
age: number;
email?: string; // 加问号表示可选
}
const lilei: User = { name: "李雷", age: 28 };
type 是类型别名,能干 interface 干的活,还能表达 interface 表达不了的东西,比如联合、交叉、从泛型推导出来的形状:
type ID = string | number;
type Admin = User & { role: "admin" };
我的经验法则很简单:平铺的对象形状默认用 interface,因为它支持声明合并、错误信息也更可读;一旦要写联合类型或者从泛型计算出来的类型,就换 type。两者在普通对象上可以互换,不用纠结。
联合类型与泛型:让类型跟着数据走
联合类型 A | B 表达「这个值是 A 或者 B」,是建模状态最常用的工具。配合可辨识联合,编译器能帮你堵住漏处理的分支:
type State =
| { status: "loading" }
| { status: "success"; data: string }
| { status: "error"; message: string };
function render(s: State) {
if (s.status === "success") {
return s.data; // 这里 TS 知道一定有 data
}
}
泛型则是把类型当参数传,写一次逻辑适配多种类型:
function first<T>(arr: T[]): T | undefined {
return arr[0];
}
first([1, 2, 3]); // 返回 number | undefined
first(["a", "b"]); // 返回 string | undefined
<T> 就是占位符,调用时 TS 自动推断它具体是什么。刚开始会觉得 <T> 这套符号别扭,用熟了之后会发现它是复用类型逻辑最干净的方式。
工具类型:别手写 Partial 和 Pick
TypeScript 内置了一批工具类型,专门基于已有类型生成新类型。最常用的两个是 Partial 和 Pick。
Partial<T> 把所有字段变成可选,做「更新部分字段」的函数特别合适:
function updateUser(id: number, patch: Partial<User>) {
// patch 里 name、age、email 都可以不传
}
updateUser(1, { age: 29 }); // 合法,只更新 age
Pick<T, K> 从一个类型里挑出几个字段组成新类型:
type UserPreview = Pick<User, "name" | "email">;
// 等价于 { name: string; email?: string }
我见过太多 PR 里有人手写一个跟 Partial 一模一样的映射类型,二三十行,其实一个内置就够了。审代码时遇到这种我都会让对方换掉,diff 立刻清爽。除了这两个,Omit、Readonly、Record、ReturnType 也都是高频选手,值得记住。
几个新手最常踩的报错
一是想表达「未知值」时随手用了 any。any 会把下游所有类型检查全关掉,报错被压住但 bug 没消失;该用的是 unknown,它逼你先 typeof 或走类型守卫再使用。
二是用 as Foo 去「修」类型错误。强制断言不做任何校验,只是把不匹配藏到运行时才炸。需要校验形状时优先用 satisfies,只有当你确实比编译器知道得更多(比如确定某个 DOM 元素的类型)才用 as。
三是联合或推导形状却选了 interface,然后一路跟它较劲。interface 表达不了联合、元组、条件类型,超出平铺对象形状就立刻换 type。
以上这些写法我都整理进了 TypeScript 速查表,100 多段都是生产代码里真出现的片段,搜索框跨标题、代码、说明一起过滤,记不住的直接搜了抄。前端栈里另一门常被一起用到的脚本语言可以看 Python 速查表,两份配合覆盖日常大半场景。
把这几类语法吃透,野生 TypeScript 代码 80% 你都能读懂、也能写对。剩下的条件类型、infer、模板字面量类型属于进阶,等基础成了肌肉记忆再啃也不迟。
Made by Toolora · Updated 2026-06-13