【TypeScript】インデックスアクセス型で配列やオブジェクトから型生成
更新日:2022/11/09
TypeScriptの型コンテキストで配列形式(ブラケット表記)を使用できます。
この表記はインデックスアクセス型と呼ばれています。
添え字を付けた時の型生成
オブジェクト型や配列型は、通常のオブジェクトや配列のようにブラケット表記( [ ] )を使って要素(プロパティ型)を取り出すことができます。
オブジェクト型は、次のようにするとプロパティの型を抜き出せます。
type ObjType = { value:number , text:string };
const a:ObjType["text"] = "hello"; // aはstring型
typeof演算子を使うと、オブジェクト(実体)からプロパティの型を抜き出せます。
const obj ={
value:100, text:"abc"
}
const a:typeof obj["text"] = "hello"; // aはstring型
typeof演算子については、次のページを参考にしてみてください。
配列は次のように使用します。
type ArrayType = boolean[];
const a:ArrayType[2] = false; // aはboolean型
上記のコードは添え字に2を指定していますが、boolean[]という型は全ての要素がboolean型なので、他の数値を添え字で指定しても同じ結果になります。
TypeScriptは配列と同じような記述で、型が異なるタプル型というものがあります。
次のコードは、タプル型を定義しています。
type ArrayType = [string,number,boolean];
const a:ArrayType[2] = false; // aはboolean型
const b:ArrayType[4] = 100; // Type '100' is not assignable to type 'undefined'.
// Tuple type 'ArrayType' of length '3' has no element at index '4'.
エラー内容:
タイプ '100' はタイプ 'undefined' に割り当てられません。
長さ '3' のタプル型 'ArrayType' には、インデックス '4' に要素がありません。
タプル型は添え字の位置の型が取得されます。
範囲外の添え字を指定すると、エラーが二つ出力されます。
一つ目は、範囲外の型はundefinedで型付けされているところ、異なる型をセットしたことによるもの。
二つ目は、範囲外に値をセットしたことによるものです。
タプル型については、次のページを読んでみてください。
配列型[number]
配列型またはタプル型の添え字に number を使用すると、配列内の全てのインデックスを対象にできます。
結果はunion型で返されます。
type tpl = [string,number,boolean];
const c:tpl[number] = 100; // cは、string | number | boolean のunion型
as constアサーションを使用すると、配列要素のunion型を生成できます。
const array = ["abc","def","ghi"] as const;
const c:typeof array[number] = "def"; // aは"abc" | "def" | "ghi" のunion型
as constについては、次のページを参考にしてみてください。
添え字にunion型を使用
添え字に union型を使用すると、プロパティ値の型をunion型で取得できます。
type ObjType = { value:number , text:string , flg:boolean};
const a:ObjType["text" | "flg"] = "hello"; // aは、string | boolean型
オブジェクトからunion型を取得するときは、typeof演算子を使用します。
const obj ={
value:100, text:"abc" , flg:true
}
const a:typeof obj["text" | "flg"] = "hello"; // aは、string | boolean型
全てのプロパティを対象にしたいときは、keyof演算子を使用します。
keyof演算子は、オブジェクト型のプロパティをunion型に変換してくれます。
そのため、変換結果を添え字として使用すれば目的を達成できます。
const a:ObjType[keyof ObjType] = "hello"; // aは、string | number | boolean型
const b:typeof obj[keyof typeof obj] = "hello"; // bは、string | number | boolean型
union型での添え字で得た型は、重複しません。
例えば次のコードで、ObjType2の型が string | string | string になるような気がするかもしれません。
type ObjType = { value:string , text:string , flg:string};
type ObjType2 = ObjType[keyof ObjType]; // ObjType2は、string型
しかし union型は、同じものを除外します。
今回は全て同じ型なので、string型になります。
更新日:2022/11/09
関連記事
スポンサーリンク
記事の内容について
こんにちはけーちゃんです。
説明するのって難しいですね。
「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。
裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。
掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。
ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php
このサイトは、リンクフリーです。大歓迎です。