TypeScript 2.2 introduced the object
, a type that represents any non-primitive type. It can be used to more accurately type methods such as Object.create
. Don't confuse it with the Object
type or {}
, the empty object type, though!
Before we can take a look at TypeScript's object type, we first have to know the six primitive types in JavaScript, which are Boolean, number, string, symbol, null, and undefined.
TypeScript's object type represents any value that does not have any of the above types. Here I'm declaring a local variable called obj that is of type object. If I now try to assign a value of a primitive type to obj I get a type error every single time.
For example, in line 14 the type checker tells me that type symbol is not assignable to type object, because, again, symbol is a primitive type and object describes all non-primitive types. On the other hand, if I assign a value of a complex type such as an empty object, or an empty array, or a function, the assignment expression type checks just fine.
All of this is useful because there are some methods in the JavaScript standard library that do not accept primitive values. One of these examples is object.create. If we take a look at the type declaration for object.create, we see that the parameter o is typed to be an object or a null.
Therefore, we get an error if we try to pass anything else. This is really helpful because otherwise we would have gotten this error at runtime. Perhaps confusingly TypeScript defines another type called object, which is spelled with an uppercase O.
This type describes functionality that is common to all objects in JavaScript. For instance, the two-string method that hasOwnProperty method and others. If I type obj. I can see all these methods in my auto completion list.
If I now remove the object type annotation and type obj. again I no longer get any auto completion. The obj variable is inferred to be of the empty object type, a type that represents anything that doesn't have any members on its own. This is why the TypeScript language server doesn't offer any auto completion suggestions here.
As you can see in line two, however, the call to the hasOwnProperty method is still type correct, because of course obj is an object and has access to the hasOwnProperty method. At the same time, you cannot add new properties to an object that has the empty object type.
If you wanted to allow such assignments you could add an explicit string index signature via a type annotation. In that case both the method call in line two, and the property assignment in line three, would be type correct. Finally, another solution could have been to type the entire object as any, in which case the compiler would allow, well, anything.