0leg
0leg

Reputation: 14144

Difference between 'object' ,{} and Object in TypeScript

Trying to figure out the difference between these 2 types in TypeScript:

foo: object

and

bar: {}

and type: Object ?


Example: trying to assign an object to the variable that suppose to handle headers information for a request:

headers: object;

Results in an error:

Type 'object' is not assignable to '{ [key: string]: string }`.

The same condition passes if using headers: {}, which leads to conclusion that {} has some slightly less tight requirements.

Upvotes: 131

Views: 61023

Answers (2)

AlbertK
AlbertK

Reputation: 13167

TypeScript has three confusing types: {}, Object, and object. You can't assign undefined nor null to any of those types except if the strictNullChecks compiler option is disabled.

{}

{} contains non-nullish values, that is any values except undefined and null. Note that {} does not refer to objects with no properties.

Object

Object contains values with common built-in instance properties (constructor, hasOwnProperty, isPrototypeOf, propertyIsEnumerable, toLocaleString, toString, and valueOf). It is stricter than {} since it requires some built-in properties. For instance, undefined, null, and { toString() { return 1; } } can't be assigned to Object (cf. @golmschenk's comment).

object

object contains non-primitive values, that is values that aren't of type Undefined, Null, Boolean, Number, BigInt, String, or Symbol. object was introduced in TypeScript 2.2.

Thus:

const x: {} = {};
const y: Object = {};
const z: object = {};
let headers: { [key: string]: string };
headers = x; // okay: {} is assignable to { [key: string]: string }
headers = y; // error: Object is not assignable to { [key: string]: string }
headers = z; // error: object is not assignable to { [key: string]: string }

Upvotes: 148

orad
orad

Reputation: 16056

The following example shows how different types of object behave differently:

var o: object;
o = { prop: 0 }; // OK
o = []; // OK
o = 42; // Error
o = "string"; // Error
o = false; // Error
o = null; // Error
o = undefined; // Error

var p: {}; // or Object
p = { prop: 0 }; // OK
p = []; // OK
p = 42; // OK
p = "string"; // OK
p = false; // OK
p = null; // Error
p = undefined; // Error

var q: { [key: string]: any };
q = { prop: 0 }; // OK
q = []; // OK
q = 42; // Error
q = "string"; // Error
q = false; // Error
q = null; // Error
q = undefined; // Error

var r: { [key: string]: string };
r = { prop: 'string' }; // OK
r = { prop: 0 }; // Error
r = []; // Error
r = 42; // Error
r = "string"; // Error
r = false; // Error
r = null; // Error
r = undefined; // Error

With that we can tell:

  • {} which is the same as type Object is the least specific. You can assign objects, arrays and primitives to it.
  • object is more specific and is similar to { [key: string]: any }. You can assign objects and arrays to it, but not primitives.
  • { [key: string]: string } is the most specific, that doesn't allow any primitive types, arrays or objects with a non-string value to be assigned to it.

Link to TypeScript playground

Upvotes: 91

Related Questions