メインコンテンツまでスキップ

object、Object、{}の違い

TypeScriptではオブジェクトの型注釈をするとき、プロパティの型まで指定するのが一般的です。

ts
let obj: { a: number; b: number };
ts
let obj: { a: number; b: number };

📄️ オブジェクトの型注釈

TypeScriptでオブジェクトの型注釈は、JavaScriptオブジェクトリテラルのような書き方で、オブジェクトプロパティをキーと値の型のペアを書きます。

そういった一般的な型注釈とは異なり、プロパティの型を指定せず、ざっくり「オブジェクトであること」を型注釈する方法もあります。object型やObject型、{}型を使うものです。

ts
let a: object;
let b: Object;
let c: {};
ts
let a: object;
let b: Object;
let c: {};

これらはどれもオブジェクトの型の値ならどんなものでも代入可能になる型です。

ts
const a: object = {}; // OK
const b: Object = {}; // OK
const c: {} = {}; // OK
ts
const a: object = {}; // OK
const b: Object = {}; // OK
const c: {} = {}; // OK

object型、Object型、{}型の違い

object型やObject型、{}型の3つは類似する部分がありますが、object型と他の2つは異なる点があります。

object型

object型はオブジェクトだけが代入できる型です。JavaScriptの値はプリミティブ型かオブジェクトの2つに大分されるので、object型はプリミティブ型が代入できない型とも言えます。

ts
let a: object;
a = { x: 1 }; // OK
a = [1, 2, 3]; // OK。配列はオブジェクト
a = /a-z/; // OK。正規表現はオブジェクト
 
// プリミティブ型はNG
a = 1;
Type 'number' is not assignable to type 'object'.2322Type 'number' is not assignable to type 'object'.
a = true;
Type 'boolean' is not assignable to type 'object'.2322Type 'boolean' is not assignable to type 'object'.
a = "string";
Type 'string' is not assignable to type 'object'.2322Type 'string' is not assignable to type 'object'.
ts
let a: object;
a = { x: 1 }; // OK
a = [1, 2, 3]; // OK。配列はオブジェクト
a = /a-z/; // OK。正規表現はオブジェクト
 
// プリミティブ型はNG
a = 1;
Type 'number' is not assignable to type 'object'.2322Type 'number' is not assignable to type 'object'.
a = true;
Type 'boolean' is not assignable to type 'object'.2322Type 'boolean' is not assignable to type 'object'.
a = "string";
Type 'string' is not assignable to type 'object'.2322Type 'string' is not assignable to type 'object'.

📄️ プリミティブ以外はすべてオブジェクト

JavaScriptでは、プリミティブ型以外のものはすべてオブジェクトです。オブジェクトには、クラスから作ったインスタンスだけでなく、クラスそのものや配列、正規表現もあります。

Object型

Object型はインターフェースです。valueOfなどのプロパティを持つ値なら何でも代入できます。したがって、Object型にはnullundefinedを除くあらゆるプリミティブ型も代入できます。string型やnumber型などのプリミティブ型は自動ボックス化により、オブジェクトのようにプロパティを持てるからです。

ts
let a: Object;
a = {}; // OK
 
// ボックス化可能なプリミティブ型OK
a = 1; // OK
a = true; // OK
a = "string"; // OK
 
// nullとundefinedはNG
a = null;
Type 'null' is not assignable to type 'Object'.2322Type 'null' is not assignable to type 'Object'.
a = undefined;
Type 'undefined' is not assignable to type 'Object'.2322Type 'undefined' is not assignable to type 'Object'.
ts
let a: Object;
a = {}; // OK
 
// ボックス化可能なプリミティブ型OK
a = 1; // OK
a = true; // OK
a = "string"; // OK
 
// nullとundefinedはNG
a = null;
Type 'null' is not assignable to type 'Object'.2322Type 'null' is not assignable to type 'Object'.
a = undefined;
Type 'undefined' is not assignable to type 'Object'.2322Type 'undefined' is not assignable to type 'Object'.

📄️ ボックス化

多くの言語では、プリミティブは一般的にフィールドやメソッドを持ちません。プリミティブをオブジェクトのように扱うには、プリミティブをオブジェクトに変換する必要があります。プリミティブからオブジェクトへの変換をボックス化(boxing)と言います。

Object型はTypeScriptの公式ドキュメントで使うべきでないとされています。理由はプリミティブ型も代入できてしまうためです。もしオブジェクトならなんでも代入可にしたい場合は、代わりにobject型を検討すべきです。

{}型

{}型は、プロパティを持たないオブジェクトを表す型です。プロパティを持ちうる値なら何でも代入できます。この点はObject型と似ていて、nullundefinedを除くあらゆる型を代入できます。

ts
let a: {};
a = {}; // OK
 
// ボックス化可能なプリミティブ型OK
a = 1; // OK
a = true; // OK
a = "string"; // OK
 
// nullとundefinedはNG
a = null;
Type 'null' is not assignable to type '{}'.2322Type 'null' is not assignable to type '{}'.
a = undefined;
Type 'undefined' is not assignable to type '{}'.2322Type 'undefined' is not assignable to type '{}'.
ts
let a: {};
a = {}; // OK
 
// ボックス化可能なプリミティブ型OK
a = 1; // OK
a = true; // OK
a = "string"; // OK
 
// nullとundefinedはNG
a = null;
Type 'null' is not assignable to type '{}'.2322Type 'null' is not assignable to type '{}'.
a = undefined;
Type 'undefined' is not assignable to type '{}'.2322Type 'undefined' is not assignable to type '{}'.

object型、Object型、{}型の代入範囲

object型やObject型、{}型の代入範囲をまとめると次の図のようになります。

学びをシェアする

TypeScriptにはよく似た型にobject、Object、{}がある。どれも「オブジェクト」を指す型。

✅object、Object、{}の違い
1️⃣object型: オブジェクトのみ代入可能
2️⃣Object型、{}型: オブジェクトとnull、undefinedを除くプリミティブ型が代入可能

『サバイバルTypeScript』より

この内容をツイートする