TypeScript シンボルの種類

導入

シンボルは、ES2015 で導入された新しいプリミティブ型の値です。これは文字列に似ていますが、各シンボル値は一意であり、他の値と等しくありません。

シンボル値は Symbol() 関数を通じて生成されます。 TypeScript では、シンボルの種類は symbol で表されます。

x:symbol = Symbol(); とします。
y:symbol = Symbol(); とします。

x === y // false

上記の例では、変数 xy の型は両方とも symbol であり、両方とも Symbol() を使用して生成されますが、それらは等しくありません。

固有のシンボル

「symbol」タイプにはすべての Symbol 値が含まれますが、特定の Symbol 値を表すことはできません。

たとえば、「5」が特定の数値である場合、それはリテラルの「5」で表され、これがその値の型でもあります。ただし、Symbol 値にはリテラルがなく、変数を介して参照する必要があるため、単一の Symbol 値のみを含む値の型を記述することはできません。

この問題を解決するために、TypeScript は、単一の特定の Symbol 値を表す symbol のサブタイプである uniqueSymbol を設計しました。

「ユニークシンボル」は単一の値を表すため、このタイプの変数の値は、「let」ではなく「const」コマンドでのみ宣言できます。

// 正しい
const x:ユニークシンボル = Symbol();

// エラーを報告する
y:一意のシンボル = Symbol(); とします。

上の例では、「let」コマンドで宣言された変数は「uniquesymbol」型にすることはできず、エラーが報告されます。

const コマンドが変数に Symbol 値を代入する場合、変数の型はデフォルトで uniquesymbol になるため、型は省略できます。

const x:ユニークシンボル = Symbol();
// と同等
const x = シンボル();

「ユニークシンボル」タイプとして宣言された各変数は異なる値を持ち、実際には 2 つの値タイプに属します。

const a:一意のシンボル = Symbol();
const b:ユニークシンボル = Symbol();

a === b // エラーを報告する

上の例では、変数「a」と変数「b」の型はどちらも「ユニークシンボル」ですが、実際には2つの値の型です。異なる型の値は絶対に等しくないため、最後の行ではエラーが報告されます。

Symbol は文字列に似ているため、次の例を参照して理解できます。

const a:'こんにちは' = 'こんにちは';
const b:'世界' = '世界';

a === b // エラーを報告する

上の例では、変数 ab はどちらも文字列ですが、異なる値の型に属しているため、厳密な等価演算子を使用して比較することはできません。

また、変数 a と変数 b には 2 つの型があるため、一方を他方に代入することはできません。

const a:一意のシンボル = Symbol();
const b:ユニークシンボル = a; // エラー

上記の例では、変数「a」と変数「b」の型はどちらも「ユニークシンボル」ですが、実際には型が異なるため、「a」を「b」に代入するとエラーが報告されます。

上記の例の変数 b の型を変数 a と同じ ユニーク シンボル 値の型として記述する場合、型 typeof a としてのみ記述できます。

const a:一意のシンボル = Symbol();
const b:typeof a = a;

ただし、同じパラメータを持つ Symbol.for() メソッドは同じ Symbol 値を返すことがわかっています。現在、TypeScript はこの状況を認識できないため、同じ Symbol 値に等しい一意のシンボル タイプ変数が複数存在する可能性があります。

const a:一意のシンボル = Symbol.for('foo');
const b:ユニークシンボル = Symbol.for('foo');

上記の例では、変数 ab は 2 つの異なる値の型ですが、実際にはそれらの値は同じです。

固有のシンボル タイプはシンボル タイプのサブタイプであるため、前者を後者に割り当てることはできますが、その逆はできません。

const a:一意のシンボル = Symbol();

const b:symbol = a;

const c:ユニークシンボル = b;

上記の例では、一意のシンボル タイプ (変数 a) をシンボル タイプ (変数 b) に代入しても問題ありませんが、シンボル タイプ (変数 b) を代入するとエラーが報告されます。一意のシンボル タイプ (変数 c)。

固有のシンボル タイプの機能の 1 つは属性名として使用され、他の属性名と競合しないことが保証されます。特定のシンボル値を属性名として使用する場合、そのタイプはシンボルではなく一意のシンボルのみにすることができます。

const x:固有のシンボル = Symbol();
const y:symbol = Symbol();

インターフェース Foo {
  [x]: 文字列; // 正しい
  [y]: 文字列; // エラーレポート
}

上記の例では属性名として変数 y を使用していますが、y の型がシンボルであり固定値ではないためエラーとなります。

「ユニーク シンボル」タイプはクラスの属性値としても使用できますが、クラスの「読み取り専用静的」属性にのみ割り当てることができます。

クラスC {
  static readonly foo:一意のシンボル = Symbol();
}

上記の例では、静的読み取り専用プロパティ foo の型は uniqueSymbol です。現時点では、この属性を確実に固定するために staticreadonly という 2 つの修飾子が必須であることに注意してください。

型推論

変数の宣言時に型が指定されていない場合、TypeScript は Symbol 値変数の型を推測します。

「let」コマンドで宣言された変数。推論される型はシンボルです。

// 型はシンボルです
x = シンボル(); とします。

const コマンドで宣言された変数は、一意のシンボルとして推論された型を持ちます。

// 型は一意のシンボルです
const x = シンボル();

ただし、「const」コマンドで宣言された変数がシンボル型の別の変数に代入されている場合、推論される型はシンボルになります。

x = シンボル(); とします。

// 型はシンボルです
定数 y = x;

「let」コマンドによって宣言された変数が、一意のシンボル型の別の変数に割り当てられた場合、推論される型は引き続きシンボルになります。

const x = シンボル();

// 型はシンボルです
y = x とします。

作者: wangdoc

アドレス: https://wangdoc.com/

ライセンス: クリエイティブ・コモンズ 3.0