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.
TypeScript has three confusing types: Object
, {}
and object
.
You can assign null
and undefined
to all three types if strictNullChecks
compiler option is disabled otherwise the compile error occurs.
Object
Contains stuff (like toString()
, hasOwnProperty()
) that is present in all JavaScript objects. Any value (primitive, non-primitive) can be assigned to Object
type.
{}
{}
is an empty object. It is pretty the same as Object
in runtime but different in compile time. In compile time {}
doesn't have Object
's members and Object
has more strict behavior (see the @golmschenk's comment).
object
object
was introduced in TypeScript 2.2. It is any non-primitive type. You can't assign to it any primitive type like bool
, number
, string
, symbol
.
Thus, if you will try this:
var strictTypeHeaders: { [key: string]: string } = {}; // non-primitive type
var header: object = {};
header = strictTypeHeaders; // its OK
strictTypeHeaders = header; // causes error "Type 'object' is not assignable to type '{ [key: string]: string }`"
you will get the compile error on the last line. This happens because { [key: string]: string }
type is more specific than object
type. There is no any error on header = strictTypeHeaders
since both types are non-primitive and object
is more common type than { [key: string]: string }
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 typeObject
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