一意性が保証されており、代入や比較ができない[[Symbol (JavaScript)|Symbol]]。
利用できるシーン/できないシーンは以下の通り。
| シーン | unique symbol? | コード例 |
| -------------------------------------------------------- | ----------------- | ----------------------------------------------------- |
| `const`で明示的に宣言 | **unique symbol** | `declare const x: unique symbol;` |
| `const`で`Symbol()`を代入 | **unique symbol** | `const x = Symbol();` |
| 明示的に`Symbol()`を代入 | **unique symbol** | `let x: unique symbol = Symbol();` |
| 明示的に`Symbol.for()`を代入 | **unique symbol** | `let x: unique symbol = Symbol.for("key");` |
| `static readonly`のプロパティに`Symbol()`を代入 | **unique symbol** | `class Inf { static readonly x = Symbol() }` |
| `const`で`Symbol.for()`を代入 | symbol | `const x = Symbol.for("key");` |
| `static readonly`のプロパティに`Symbol.for("key")`を代入 | symbol | `class Inf { static readonly x = Symbol.for("key") }` |
| `let`で明示的に宣言 | エラー | `declare const x: unique symbol;` |
利用例として、[[公称型]]を実現するために付与する一意なプロパティなどが考えられる。
### [[構造的部分型]]
```typescript
class Dog {
constructor(public name: string) { }
}
class Cat {
constructor(public name: string) { }
}
function nyan(cat: Cat) {
console.log(cat.name);
}
const dog = new Dog("pochi");
// 引数はCatだがdog(: Dog)はCatと同じプロパティを持つため動作する
nyan(dog);
```
### [[公称型]]
```typescript
const DogType = Symbol();
class Dog {
private [DogType]: void;
constructor(public name: string) { }
}
const CatType = Symbol();
class Cat {
private [CatType]: void;
constructor(public name: string) { }
}
function nyan(cat: Cat) {
console.log(cat.name);
}
const dog = new Dog("pochi");
// プロパティが違うのでちゃんとエラーにしてくれる
// TS2345: Argument of type 'Dog' is not assignable to parameter of type 'Cat'.
// Property '[CatType]' is missing in type 'Dog' but required in type 'Cat'.
nyan(dog);
```