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 进阶的实用工具。

笔记加载中…