TypeScript Symbol
Symbol 是 ES6 新增的原始类型,用来生成「独一无二」的值。它常用于创建不会冲突的对象属性、模拟私有成员,以及配合内置 Symbol 实现自定义迭代等功能。
创建 Symbol
每次调用 Symbol() 都会产生一个新值,即使描述相同也不相等;描述只用于调试:
let s1: symbol = Symbol();
let s2: symbol = Symbol("desc");
let s3: symbol = Symbol("desc");
console.log(s1 === s2); // 输出:false
console.log(s2 === s3); // 输出:false(描述相同也不相等)
console.log(s2.toString()); // 输出:Symbol(desc)
Symbol 作对象属性名
用 Symbol 作键可以防止属性名冲突,且常规遍历不会暴露它:
let id = Symbol("id");
let user: { name: string; [id]: number } = {
name: "张三",
[id]: 1001,
};
console.log(user.name); // 输出:张三
console.log(user[id]); // 输出:1001
console.log(Object.keys(user)); // 输出:[ 'name' ]
console.log(Object.getOwnPropertySymbols(user).length); // 输出:1
Symbol.for 全局共享
Symbol.for 按描述在全局注册表中查找:存在则复用,不存在则创建,从而实现跨模块共享同一个 Symbol:
let a = Symbol.for("token");
let b = Symbol.for("token");
console.log(a === b); // 输出:true
console.log(Symbol.keyFor(b)); // 输出:token
内置 Symbol 与迭代器
对象实现 Symbol.iterator 方法即可被 for...of 遍历,数组、字符串等内置类型都实现了它:
let nums: number[] = [10, 20, 30];
let it = nums[Symbol.iterator]();
console.log(it.next()); // 输出:{ value: 10, done: false }
console.log(it.next()); // 输出:{ value: 20, done: false }
unique symbol 类型
用 const 声明的 Symbol 可用 unique symbol 标注,表示「这个值是唯一的字面量类型」,适合做类型级标记:
const ON: unique symbol = Symbol("on");
const OFF: unique symbol = Symbol("off");
type Switch = typeof ON | typeof OFF;
let state: Switch = ON;
console.log(state === ON); // 输出:true
// state = Symbol("on"); // 报错:不是同一个 unique symbol
小结
Symbol 的价值在于「唯一性」:防止键冲突、隐藏内部属性、配合 Symbol.iterator 定制遍历行为。需要跨模块共享同一标识时使用 Symbol.for,是 TypeScript 进阶的实用工具。