Typing Objects
Object Types#
Object types allow us to describe the structure of our application's data. When discussing object types, we generally mean one of the following:
A type that represents any non-primitive
A type that conveys the keys and values of an object
We'll cover both cases, starting with the first, which is achieved using the object
(lowercase o
) type.
The object type#
When we need a type that is only assignable to non-primitives, we use the built-in object
type. Attempting to assign a primitive to an object
will produce an error:
let x: object;
/**
* Assigning to primitives
* */
x = 'hi'; // Error
x = 2000; // Error
x = null; // Error
x = true; // Error
/**
* Assigning to non-primitives
* */
x = { random: true }; // OK
x = [10, 20, 30, 40]; // OK
object
is used when we expect an object whose key/value pairs are irrelevant. Attempting to access a property of an object
will produce an error:
const x: object;
x.hello(); // Error: 'hello' does not exist on type 'object'
A value with type
object
can still access methods and properties that are available to all JavaScript (and TypeScript) objects, such astoString()
andvalueOf()
, which are inherited fromObject.prototype
.
When using object
as the type of a function's parameter, the function's body and return type should not make any assumptions about the properties of the given object.
A real-world use case for object
is a function that returns the number of keys in an object:
function numKeys(obj: object): number {
return Object.keys(obj).length;
}
const products = {
'id1': 'Toilet paper',
'id2': 'Water',
'id3': 'Keyboard',
};
const numProducts = numKeys(products); // 3
Because numKeys
's body and return value do not depend on any specific properties of the input object, we use object
for our parameter's type to ensure that only non-primitives can be passed to the function. Any primitives passed to numKeys
will produce an error:
numKeys('ab'); // Error
numKeys(true); // Error
numKeys(2000); // Error
object
,Object
, and{}
#
Object
refers to an interface that defines properties and methods that are shared by all objects, such asvalueOf()
andtoString()
.{}
refers to the empty object type, which in practice behaves the same asObject
as it inheritsObject
's properties without adding any additional properties. TheObject
and{}
types are misleading as they are assignable to primitives in addition to objects:
const x: Object = 'pizza'; // OKconst y: {} = true; // OK
Whereas the
object
type produces an error when assigned to primitives:
const z: object = 'apple'; // Error: 'apple' is not assignable to object
For this reason, we prefer
object
in all instances that require a type that is only assignable to non-primitives.
This page is a preview of Beginners Guide to TypeScript