一意性が保証されており、代入や比較ができない[[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); ```