TypeScript
  • Introduction
  • Introduction
    • What is TypeScript?
    • Why TypeScript?
    • Setup
  • Beginner
    • Basic types
      • Primitive types
      • Arrays and tuples
      • Enums
      • Any type
    • Objects
    • Type aliases
    • Interfaces
    • Functions
      • Function signatures
      • Void type
      • Functions as types
    • Union types
    • Type guards
    • Intersection types
    • Nullable types
    • Inference
  • Resources
    • Resources
Powered by GitBook
On this page
  1. Beginner

Objects

Consider the following TypeScript code:

const band = {};
band.name = 'The Chemical Brothers'; // Error: Property 'name' does not exist on type '{}'

Seeing this error leads us to recall that TypeScript relies on duck typing to define its types in a structural manner. So TypeScript infers the type of band to be not only an object, but importantly, an empty object.

We can prove TypeScript infers the type based on the object's structure (i.e., its property names and their types) by trying to assign a differently structured object.

In this example, we get an error because the property types must match:

let band = {
  name: 'The Chemical Brothers',
  yearFormed: 1989,
};

band = {
  name: 311,
  yearFormed: 1988,
}; // Error: Type '{ name: number; yearFormed: number; }' is not assignable to type '{ name: string; yearFormed: number; }'.

The property names must also match:

band = {
  a: 'The Chemical Brothers',
  b: 1989,
}; // Error: Type '{ a: string; b: number; }' is not assignable to type '{ name: string; yearFormed: number; }'

When declaring a new object, you can explicitly annotate the object's type using the following notation:

const band: {
  name: string,
  yearFormed: number,
} = {
  name: 'The Chemical Brothers',
  yearFormed: 1989,
};

This way of type annotating an object literal is uncommon because of an inherent limitation.

Take the following example, where we have two objects of the same type:

const openingBand: {
  name: string,
  yearFormed: number,
} = {
  name: 'Minutemen',
  yearFormed: 1980,
};

const headliningBand: {
  name: string,
  yearFormed: number,
} = {
  name: 'Black Flag',
  yearFormed: 1976,
};

We can immediately recognize some issues with this code. For one, we now have duplicate types. Secondly, our types are out of sync — meaning if we want to make a change to the type in one place, we must update all other instances where that same object literal type annotation is used since they are declared independently.

PreviousAny typeNextType aliases

Last updated 6 years ago

The following sections are about and , which resolve these issues, making sharing and reusing types across a codebase much more manageable.

type aliases
interfaces