135

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.

3
  • I wonder if there is any, because there does not appear to be. Commented Mar 24, 2018 at 12:57
  • Under some circumstances TypeScript would trigger an error for one of those. So there might be some. Commented Mar 24, 2018 at 13:05
  • Well, they are assignable to each other, so please add any such error cases you are aware of to the question. Commented Mar 24, 2018 at 13:07

2 Answers 2

154

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 }
Sign up to request clarification or add additional context in comments.

5 Comments

Please don't say "Any object (primitive, non-primitive, null and etc)" but "any value". A primitive is not an object.
Good answer. Would be great to add the reference urls (if any).
In TS if a function parameter is of type: { }, I cannot call that function with a value of null.. Seems to contradict above.
Object and {} are not quite the same. Built-in methods have pre-defined enforced types for Object but not for {}. So let x: {} = {toString() { return 2 }} will run, but let x: Object = {toString() { return 2 }} will result in an error (because toString requires returning a string for Object but not for {}).
Clarification for others: When this answer says "type X contains Y values", it means "any Y values are valid instances of type X". For example: "object contains non-primitive values" means that any non-primitive value is a valid object.
94

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

1 Comment

note that console.log(typeof o) is 'object' in all these cases

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.