book icon indicating copy to clipboard operation
book copied to clipboard

質問: JavaScriptのオブジェクトリテラルのキーにシンボルの値を使う場合、なぜブランケットで囲むのか?

Open kotsgcp opened this issue 2 years ago • 1 comments

以下のコードのコメントをつけた部分なんですが、シンボル型がキーの場合のみキーをブラケットで囲うのはなぜでしょうか?

type Identifier = symbol | 1;
type Sample = {
  [P in Identifier]: string;
};

const sample: Sample = {
  1: "pork", // キーにブラケットなし
  [Symbol("thick")]: "thin", // キーにブラケットあり
};

関連ページ: https://typescriptbook.jp/reference/type-reuse/mapped-types

kotsgcp avatar Mar 29 '22 01:03 kotsgcp

@kotsgcp ご回答が遅くってすみません。

まず、この部分は、

const sample = {
  1: "pork", // キーにブラケットなし
  [Symbol("thick")]: "thin", // キーにブラケットあり
};

TypeScriptではなく、JavaScriptの文法規則に従う部分だとご理解ください。

質問を言い換えると次のように整理だきるかと思います。

JavaScriptのオブジェクトリテラルのキーにシンボルの値を使う場合、なぜブランケットで囲むのか?

JavaScriptのオブジェクトリテラルでは、キーを動的に指定する場合、ブランケットで囲む必要があります。

たとえば、"name"という値がkeyという変数に代入されていたとき、

const key = "name";

この変数keyを使って{ name: "alice" }というオブジェクトを作りには、keyをブランケットで囲みます。

const person = { [key]: "alice" };

ちなみに、ブランケットを使わない次のような書き方は、{ key: "alice" }になってしまいます。

const person = { key: "alice" };
//=> { "key": "alice" };

話を戻して、今度は逆に変数keyをインライン展開することを考えてみましょう。

const person = { [key]: "alice" };

上はkeyに値"name"を代入して、

const person = { ["name"]: "alice" };

に書き換えられます。この書き方もJavaScriptの文法的にOKで、普通に動きます。

・・・

シンボルの値にもこの規則が適用されます。

たとえば、"Symbol("thick")"という値がkeyという変数に代入されていたとき、

const key = Symbol("thick");

この変数をキーに{ Symbol("thick") : "thin" }のようなオブジェクトを作るには次のようにします。

const sample = { [key]: "thin" };

これの変数keyをインライン展開すると、

const sample = { [Symbol("thick")]: "thin" };

になります。

まとめると、変数をキーにする場合、ブランケットが必要だから(シンボルに限った話でない)というのが回答になります。

ほしい答えになっていますでしょうか?不明点があれば気軽に聞いてください。

suin avatar Apr 01 '22 10:04 suin

Mapped Typesの解説がシンボルを使わない内容になったことと、追加のご質問もなさそうなのでクローズします。

suin avatar Feb 26 '23 00:02 suin