オブジェクトの型注釈 (type annotation)
TypeScriptでオブジェクトの型注釈は、JavaScriptオブジェクトリテラルのような書き方で、オブジェクトプロパティをキーと値の型のペアを書きます。
ts
letbox : {width : number;height : number };// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^型注釈box = {width : 1080,height : 720 };
ts
letbox : {width : number;height : number };// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^型注釈box = {width : 1080,height : 720 };
オブジェクトの型注釈をしておくと、型の誤りをコンパイラーが警告してくれるようになります。
ts
letbox : {width : number;height : number };// 誤ってプロパティに文字列を代入したType 'string' is not assignable to type 'number'.2322Type 'string' is not assignable to type 'number'.box = {: "1080", width height : 720 };// 誤ってheightを指定し忘れたProperty 'height' is missing in type '{ width: number; }' but required in type '{ width: number; height: number; }'.2741Property 'height' is missing in type '{ width: number; }' but required in type '{ width: number; height: number; }'.= { box width : 1080 };
ts
letbox : {width : number;height : number };// 誤ってプロパティに文字列を代入したType 'string' is not assignable to type 'number'.2322Type 'string' is not assignable to type 'number'.box = {: "1080", width height : 720 };// 誤ってheightを指定し忘れたProperty 'height' is missing in type '{ width: number; }' but required in type '{ width: number; height: number; }'.2741Property 'height' is missing in type '{ width: number; }' but required in type '{ width: number; height: number; }'.= { box width : 1080 };
プロパティの区切り文字には、オブジェクトリテラルのようにカンマ,
も使えますが、セミコロン;
を用いるほうを推奨します。理由は、コード整形ツールPrettierがオブジェクトの型注釈を直すとき、カンマをセミコロンに置き換えるためです。
オブジェクトの型注釈は途中で改行することもできます。改行した場合、プロパティの区切り文字は省略できます。
ts
letbox : {width : number;height : number;};box = {width : 1080,height : 720 };
ts
letbox : {width : number;height : number;};box = {width : 1080,height : 720 };
インラインの型注釈の代わりに、型エイリアスを使った型注釈の書き方もできます。
ts
// 型エイリアスtypeBox = {width : number;height : number };letbox :Box = {width : 1080,height : 720 };// ^^^型注釈
ts
// 型エイリアスtypeBox = {width : number;height : number };letbox :Box = {width : 1080,height : 720 };// ^^^型注釈
📄️ 型エイリアス
TypeScriptでは、型に名前をつけられます。名前のついた型を型エイリアス(タイプエイリアス; type alias)と呼びます。
メソッドの型注釈
オブジェクトの型注釈には、メソッドの型注釈を書くこともできます。書き方はJavaScriptのメソッド構文に引数と戻り値の型注釈を加えたようなものになります。
ts
letcalculator : {sum (x : number,y : number): number;};calculator = {sum (x ,y ) {returnx +y ;},};
ts
letcalculator : {sum (x : number,y : number): number;};calculator = {sum (x ,y ) {returnx +y ;},};
メソッドの型注釈は関数構文の書き方もできます。
ts
letcalculator : {sum : (x : number,y : number) => number;};
ts
letcalculator : {sum : (x : number,y : number) => number;};
メソッド構文(method syntax)の型注釈と関数構文(function syntax)の型注釈は、基本的に同じ意味ですが、コンパイラーオプションのstrictFunctionTypes
を有効にした場合に関数構文の書き方は、メソッド引数のチェックが双変(bivariant)から共変(covariant)へと厳格になります。この詳細についてはstrictFunctionTypes
の説明を参照してください。
📄️ strictFunctionTypes
引数型の変性のチェックを厳しくする
オブジェクトの型推論
オブジェクトの値を変数宣言で代入する場合、型注釈を省略できます。値から型が自動的に判別されます。これを型推論といいます。
ts
letbox = {width : 1080,height : 720 };
ts
letbox = {width : 1080,height : 720 };
メソッドを持つオブジェクトリテラルでも型推論が働きます。ただし、メソッドの場合は引数の型注釈は必要です。
ts
letcalculator = {sum (x : number,y : number) {returnx +y ;},};calculator ;
ts
letcalculator = {sum (x : number,y : number) {returnx +y ;},};calculator ;
Record<Keys, Type>
連想配列のようなキーバリューのオブジェクトの型を定義する場合、ユーティリティ型のRecord
を使う方法もあります。
ts
letfoo :Record <string, number>;foo = {a : 1,b : 2 };
ts
letfoo :Record <string, number>;foo = {a : 1,b : 2 };
📄️ Record<Keys, Type>
キー・バリューからオブジェクト型を作る
object
型
オブジェクトの型注釈にはobject
型を用いることもできます。
ts
letbox : object;box = {width : 1080,height : 720 };
ts
letbox : object;box = {width : 1080,height : 720 };
object
型の使用はお勧めしません。第1の理由は、object
型には何のプロパティがあるかの情報がないためです。そのため、box.width
を参照するとコンパイルエラーになります。
ts
Property 'width' does not exist on type 'object'.2339Property 'width' does not exist on type 'object'.box .; width
ts
Property 'width' does not exist on type 'object'.2339Property 'width' does not exist on type 'object'.box .; width
第2の理由はどんなオブジェクトでも代入できるからです。期待しない値も代入できてしまうので、コードの問題に気づきにくくなります。
ts
letbox : object;box = {wtdih : 1080,hihget : 720 }; // スペルミス
ts
letbox : object;box = {wtdih : 1080,hihget : 720 }; // スペルミス
オブジェクトを型注釈する場合は、object
型はできるだけ使わずに、プロパティまで型を定義することをお勧めします。
学びをシェアする
・TypeScriptでオブジェクトを型注釈するには、プロパティキーごとに型を定義する
例: { width: number; height: number}
・変数にオブジェクトを代入すると型推論が効く
・安全性の観点からobject型を用いるのは避ける
『サバイバルTypeScript』より
関連情報
📄️ object、Object、{}の違い
TypeScriptではオブジェクトの型注釈をするとき、プロパティの型まで指定するのが一般的です。
📄️ インターフェース
インターフェースはクラスが実装すべきフィールドやメソッドを定義した型です。クラスはインターフェースを実装することで、インターフェースが求めるメソッド名や引数の型に則っているかをチェックすることができます。