TypeScript 如何表示独一无二的值?

267 阅读2分钟

symbol 是 ES6 中新增的原始数据类型,就像 numberstring 一样,用于表示独一无二的值。

unique symbolsymbol 的子类型,也可以说是 symbol 的加强版。

在 Vue.js 的源码中,有许多地方用到了 unique symbol 类型:

// packages/runtime-core/src/vnode.ts

export const Text: unique symbol = Symbol.for('v-txt')
export const Comment: unique symbol = Symbol.for('v-cmt')
export const Static: unique symbol = Symbol.for('v-stc')

上面代码摘自 Vue.js 3.5.5 版本

unique symbol 类型与 symbol 一样,仅可以通过调用 Symbol() 、Symbol.for() 或者显示类型注解来创建:

const sym1: unique symbol = Symbol.for('sym1');

const sym2: unique symbol = Symbol('sym2');

declare const sym3: unique symbol;

unique symbol 类型只允许在常量声明(const)和只读静态属性(static readonly)上使用,在 let 中声明 unique symbol 类型会报错:

2.png

symbol 类型没有这些限制:

class MyClass {
  StaticSymbol = Symbol();
}

let sym2 = Symbol.for('sym2');

unique symbol 类型的值也不能够用于互相比对和重新赋值的,例如下面代码中判断两个 unique symbol 类型的值是否相等和重新赋值时,TypeScript 中会报错:

3.png

但是换成 symbol 类型的值,是可以进行相互比对和重新赋值的:

let sym1 = Symbol.for('sym');
let sym2 = Symbol.for('sym');

if (sym1 === sym2) {
  console.log('相等')
}

sym1 = Symbol('sym1')

上面的代码不会产生报错。

如果使用 const 声明 Symbol()Symbol.for() 方法返回的 symbol 值,TypeScript 会自动将其转换为 unique symbol 类型:

4.png

总结

symbol 是 ES6 中新增的原始数据类型,用于表示独一无二的值。

在 TypeScript 中,unique symbolsymbol 的子类型,也可以说是 symbol 的加强版。注意 JS 中是没有 unique symbol 的,unique symbol 是 Typscript 中的概念。

unique symbol 类型的值只允许在常量声明(const)和只读静态属性(static readonly)上使用,在 let 中声明或非只读静态属性属性上使用会报错,而 symbol 没有这个限制。

unique symbol 类型的值不允许互相比对和重新赋值,symbol 也没有这个限制。同时,使用 const 声明的 Symbol()Symbol.for() 方法返回的 symbol 值,TypeScript 会自动将其转换为 unique symbol 类型。

unique symbol 类型有助 TypeScript 提供更强大的类型检查,同时能防止代码中相关的唯一标识被意外的修改,增强代码的健壮性。