インデックスアクセス型【個人学習まとめ】
インデックスアクセス型
学習中にインデックスアクセス型で躓いたので、調べたことをまとめました。
今回、躓いたコードは次のようなコードです。
const STATUS = ["todo", "working", "done"] as const;
type Status = (typeof STATUS)[number];
普段から TypeScript を触れている型であれば、このコードのtype Status = (typeof STATUS)[number];
部分はどんなことをしているコードがパッと判断できる方が多いと思います。
もし判断が付かなくてもこの記事で学習しましょう!!!
type xxx = (typeof ○○○)[number]
は何をしているのか
結論からいうとこれは**「配列内の要素の型を取り出す」**ということをやっています。
少しずつ確認してみましょう。
as const
本題に入る前に一か所だけ確認します。
これはconst
アサーションと呼ばれ、変数が読み取り専用であることを示します。
これにより、配列を読み取り専用のタプルとして扱います。
const アサーションの記事
typeof arr[]
typeof
演算子は JavaScirpt と TypeScript でそれぞれ違いがあります。
JavaScript は指定した値の型を絞り込む、TypeScript では変数から型を抽出し、型情報を返却するという違いです。以前の記事で紹介しました
今回は TypeScript のtypeof
演算子が使われています。
分かりやすいように[number]
部分を取り除いて、型情報が返却されているか見てみます。
const STATUS = ["todo", "working", "done"] as const;
+ type Status_1 = typeof STATUS;
+ type Status_2 = (typeof STATUS)[number];
- type Status = (typeof STATUS)[number];
では、型Status_1
の中身はどうなっているのかというと・・・
type Status_1 = readonly ["todo", "working", "done"];
となり、STATUS
配列全体の型を取得しています。
ではStatus_2
はどうなっているでしょうか。
type Status_2 = "todo" | "working" | "done";
ユニオン型となっています。
初めに書いたように、type xxx = (typeof ○○○)[number]
では**「配列内の要素の型を取り出す」**ということをやっています。
つまり分解してみると
STATUS[0] → "todo"型
STATUS[1] → "working"型
STATUS[2] → "done"型
となります。
これらをすべて集める・・・
"todo" | "working" | "done";
というユニオン型になります。Status_2
の中身と一致していますね!
まとめ
あらためて最初のコードを見てみましょう。
const STATUS = ["todo", "working", "done"] as const;
type Status = (typeof STATUS)[number];
ここまできたらこのコードでどんなことをやっているか理解できますね!
構文 | 意味 |
---|---|
typeof arr | 配列全体の型 |
typeof arr[number] | 配列の要素型(Union) |
- [number] は配列の要素型を取り出すためのインデックスアクセス型
- as const を使うことで、文字列リテラル型として扱える
おまけ
インデックスアクセス型を利用することによって、将来的に新たなステータスの型を追加した場合、STATUS
にその要素を追加するだけで型Status
に反映されるようになります!
例) review
を追加
const STATUS = ["todo", "working", "done", "review"] as const;
type Status = (typeof STATUS)[number];
// → "todo" | "working" | "done" | "review"
Discussion