TypeScript 的类型系统帮助我们更清晰地表达数据结构。常见类型包括原始类型、数组、元组、枚举、联合类型和字面量类型。
原始类型
let title: string = "TypeScript";
let count: number = 10;
let enabled: boolean = true;
let big: bigint = 9007199254740991n;string 表示文本,number 表示整数和浮点数,boolean 表示真假值。
数组
数组可以用两种常见方式声明。
let numbers: number[] = [1, 2, 3];
let names: Array<string> = ["Alice", "Bob"];如果数组中元素类型固定,推荐明确写出元素类型。
元组
元组适合表达固定长度、固定位置含义的数据。
let user: [string, number] = ["Alice", 25];
let option: [string, boolean?] = ["dark"];
let list: [number, ...string[]] = [1, "a", "b"];枚举
枚举用于定义一组命名常量。
enum Color {
Red,
Green,
Blue,
}
const favorite: Color = Color.Green;实际项目中也常用联合字面量代替枚举。
type Direction = "up" | "down" | "left" | "right";联合类型
联合类型表示一个值可以是多种类型之一。
let id: string | number;
id = "u_1";
id = 1001;联合类型很适合处理 API 参数、表单输入和状态值。
字面量类型
字面量类型让变量只能取指定值。
type Gender = "male" | "female";
type Status = "idle" | "loading" | "success" | "error";它可以让状态建模更安全,也能减少魔法字符串带来的错误。
延伸理解
复习这篇时,不要只记住名词,要把重点放在 原始类型、数组、元组、枚举、联合类型、字面量类型和类型建模。这类知识如果只停留在定义层面,很容易在面试或项目中答得很散。更好的理解方式是把它放进一个具体场景:谁在调用它,输入从哪里来,失败后谁负责恢复,数据或状态会不会被重复处理。
- TypeScript 的价值是把运行时不确定性尽量前移到开发阶段,但它不能替代运行时校验。
- 类型设计应优先描述业务约束,而不是为了炫技使用复杂泛型。
- 遇到第三方输入、JSON、表单和 API 响应时,要结合类型收窄或 schema 校验。
在真实项目中,可以把它当成一个判断框架:先确认输入、约束、失败场景和可观测性,再决定具体工具或写法。 如果一个方案看起来很简单,要继续追问它在规模扩大、权限变化、异常恢复和团队协作下是否仍然成立。
实践检查清单
- 明确这个知识点在系统中的位置:是开发时约束、运行时能力、基础设施能力,还是协作流程。
- 写出一个最小可运行例子,并补一个失败例子;只会写 happy path 说明理解还不够稳。
- 记录常见误用:例如边界条件、权限假设、性能假设、同步/异步差异或环境差异。
- 把概念和项目经历关联起来:如果面试被追问,可以用自己的项目说明为什么这样选。
- 最后用一句话总结取舍:它牺牲了什么,换来了什么。
自测问题
- 这个主题解决的核心问题是什么?
- 如果不用当前方案,还有哪些替代方案?代价是什么?
- 最容易出错的边界条件在哪里?
- 如何在代码、测试或监控中验证它真的可靠?
项目化应用场景
可以把这类知识放到一个前后端共享类型的项目里理解:API 返回 JSON,前端先用 schema 做运行时校验,再把校验后的数据交给 TypeScript 类型系统。类型可以帮助编辑器提示和编译期检查,但不能保证网络返回一定正确。好的类型设计应该表达业务约束,例如角色、状态、权限、请求参数和响应结构,而不是所有地方都写成 string 或 any。
常见误区:
- 把 TypeScript 类型当成运行时校验。
- 为了省事使用 any,导致错误延后到线上。
- 泛型过度复杂,让调用者难以理解。