Skip to content

TypeScript Symbol

简介

Symbol 是 ES2015 新引入的一种原始类型的值。每一个 Symbol 值都独一无二。

Symbol 值通过Symbol()函数生成。

在 TypeScript 里面,Symbol 的类型使用symbol表示。

ts
let x: symbol = Symbol();
let y: symbol = Symbol();

类型推断

如果变量声明时没有给出类型,TypeScript 会推断某个 Symbol 值变量的类型。

let命令声明的变量,推断类型为 symbol。

const命令声明的变量,推断类型为 unique symbol。

unique symbol

symbol类型包含所有的 Symbol 值,但是无法表示某一个具体的 Symbol 值。

那么当有一个独一无二的 symbol 对象时,就需要有个变量引用他,那这个变量的类型应该是什么呢 ?

为了解决这个问题,TypeScript 设计了symbol的一个子类型unique symbol,它表示单个的、某个具体的 Symbol 值。

因为unique symbol表示单个值,所以这个类型的变量是不能修改值的,只能用const命令声明,不能用let声明。

ts
// 正确
const x: unique symbol = Symbol();

// 报错
let y: unique symbol = Symbol();

const命令为变量赋值 Symbol 值时,变量类型默认就是unique symbol,所以类型可以省略不写。

ts
const x: unique symbol = Symbol();
// 等同于
const x = Symbol();

每个声明为unique symbol类型的变量,它们的值都是不一样的,其实属于两个值类型。

ts
const a: unique symbol = Symbol();
const b: unique symbol = Symbol();

上面示例中,变量a和变量b的类型虽然都是unique symbol,但其实是两个值类型。不同类型的值肯定是不相等的,所以最后一行就报错了。

ts
const a: unique symbol = Symbol();
const b: unique symbol = Symbol();

// 报错,typeof a 和 typeof b 没有任何重叠之处
// neither type sufficiently overlaps with the other.
(b as typeof a).toString() 

const c: typeof a = a; // 正确,a c 指向同一个引用

不过我们知道,相同参数的Symbol.for()方法会返回相同的 Symbol 值。

js
console.log(Symbol.for("bar") === Symbol.for("bar"));// true

console.log(Symbol("bar") === Symbol("bar"));// false

const symbol1 = Symbol.for("foo");
console.log(symbol1.toString()); // "Symbol(foo)"