🆚 与 Python 的对比:Python 的 list 是动态类型,可以混合类型;TS 的 Array 默认要求元素同类型。Python 的 dict 对应 TS 的 Record 或 Map。Python 的 tuple 是不可变的,TS 的 Tuple 侧重固定长度和类型。
1. Array
两种等价的数组类型标注方式,以及常用的类型安全数组方法:
// 两种写法完全等价
const nums: number[] = [1, 2, 3];
const strs: Array<string> = ["a", "b", "c"];
// map —— 返回新数组,类型自动推断
const doubled: number[] = nums.map(n => n * 2);
// filter —— 可以用类型守卫缩窄类型
const mixed: (string | number)[] = [1, "a", 2, "b"];
const onlyStrings: string[] = mixed.filter(
(x): x is string => typeof x === "string"
);
// reduce —— 需要提供初始值的类型
const sum: number = nums.reduce((acc, cur) => acc + cur, 0);
// find / some / every
const found: number | undefined = nums.find(n => n > 2);
const hasNeg: boolean = nums.some(n => n < 0);
const allPos: boolean = nums.every(n => n > 0);
// 只读数组
const frozen: readonly number[] = [1, 2, 3];
// frozen.push(4); // ✗ 编译错误
2. Tuple(元组)
元组是固定长度、每个位置有明确类型的数组。适合函数返回多个值的场景:
// 基本元组
const point: [number, number] = [10, 20];
const entry: [string, number] = ["age", 30];
// 带标签的元组——提高可读性
type Range = [start: number, end: number];
const r: Range = [0, 100];
// 可选元素
type OptionalTuple = [string, number?];
const t1: OptionalTuple = ["hello"];
const t2: OptionalTuple = ["hello", 42];
// Rest 元素
type StringAndNumbers = [string, ...number[]];
const sn: StringAndNumbers = ["sum", 1, 2, 3, 4];
// 实际用途:函数返回多个值
function useState<T>(initial: T): [T, (v: T) => void] {
let value = initial;
const setter = (v: T) => { value = v; };
return [value, setter];
}
const [count, setCount] = useState(0);
解构元组时变量名任意,类型由位置决定。这与 Python 的 namedtuple 不同,更像 Go 的多返回值。
3. Enum(枚举)
// 数字枚举——默认从 0 开始自增
enum Direction {
Up, // 0
Down, // 1
Left, // 2
Right // 3
}
// 字符串枚举——每个成员必须显式赋值
enum Status {
Active = "ACTIVE",
Inactive = "INACTIVE",
Pending = "PENDING"
}
// const enum——编译时内联,不生成运行时对象
const enum Color {
Red = "#ff0000",
Green = "#00ff00",
Blue = "#0000ff"
}
const c = Color.Red; // 编译后直接替换为 "#ff0000"
// 数字枚举支持反向映射
console.log(Direction[0]); // "Up"
console.log(Direction.Up); // 0
枚举 vs 联合类型:大多数场景推荐用 type Status = "active" | "inactive" 联合类型替代枚举——更轻量且无运行时开销。枚举在需要反向映射或遍历成员时更有优势。
4. Map 与 Set
// Map<K, V> —— 有序键值对集合
const userMap = new Map<number, string>();
userMap.set(1, "Alice");
userMap.set(2, "Bob");
const name = userMap.get(1); // string | undefined
const exists = userMap.has(3); // false
userMap.delete(2);
console.log(userMap.size); // 1
// 遍历 Map
for (const [id, name] of userMap) {
console.log(`${id}: ${name}`);
}
// Set<T> —— 值唯一的集合
const tags = new Set<string>();
tags.add("typescript");
tags.add("javascript");
tags.add("typescript"); // 不会重复添加
console.log(tags.size); // 2
// WeakMap / WeakSet —— 键为弱引用,不阻止垃圾回收
const cache = new WeakMap<object, string>();
let obj = { id: 1 };
cache.set(obj, "cached");
// obj = null 后,cache 中的条目可被 GC 回收
5. Record 类型
Record<K, V> 用于创建键值对类型,类似 Python 的 Dict[str, T]:
// Record 作为字典
type ScoreBoard = Record<string, number>;
const scores: ScoreBoard = {
alice: 95,
bob: 87,
charlie: 92
};
// 限定键的范围
type Role = "admin" | "editor" | "viewer";
type Permissions = Record<Role, string[]>;
const perms: Permissions = {
admin: ["read", "write", "delete"],
editor: ["read", "write"],
viewer: ["read"]
};
// Record vs Map:
// Record 编译为普通对象,键只能是 string | number | symbol
// Map 键可以是任意类型,有更好的增删性能和迭代顺序保证
6. 解构与展开
// 对象解构 + 类型注解
const user = { name: "Alice", age: 30, email: "a@b.com" };
const { name, age }: { name: string; age: number } = user;
// 重命名 + 默认值
const { name: userName, role = "user" } = { name: "Bob" };
// 数组解构
const [first, second, ...rest] = [1, 2, 3, 4, 5];
// first: number, second: number, rest: number[]
// 展开运算符——合并对象
const defaults = { theme: "light", lang: "zh" };
const custom = { theme: "dark" };
const config = { ...defaults, ...custom };
// { theme: "dark", lang: "zh" }
// 展开运算符——合并数组
const arr1 = [1, 2];
const arr2 = [3, 4];
const merged = [...arr1, ...arr2]; // [1, 2, 3, 4]
// Rest 参数解构
function printInfo({ name, ...rest }: {
name: string;
age: number;
email: string;
}) {
console.log(name, rest); // rest: { age: number; email: string }
}
📝 本章要点
- ✦Array 用
T[]或Array<T>标注,filter配合类型守卫可缩窄元素类型 - ✦Tuple 适合固定结构的多值返回,支持标签、可选元素和 Rest 元素
- ✦大多数场景推荐联合类型替代 Enum;需要反向映射时用数字枚举,需要内联时用 const enum
- ✦Map/Set 是有序集合,Record 是轻量字典。根据键类型和性能需求选择
- ✦解构和展开是日常编码的核心操作,务必掌握对象和数组两种场景的类型标注