Object Types & Type Aliases

Most data in a program is objects. TypeScript lets you describe an object's shape — which properties it has and what type each one holds — and give that shape a reusable name with a type alias.

An inline object type

TS inline.ts
const book: { title: string; pages: number } = {
  title: "Dune",
  pages: 412,
};

book.pages = "long";
tsc output
error TS2322: Type 'string' is not assignable to type 'number'.

The type between the braces lists each property and its type. Properties are separated by ; or , — both are allowed.

Naming a shape with type

Repeating an inline object type everywhere is error-prone. A type alias gives it a name:

TS alias.ts
type Book = {
  title: string;
  pages: number;
};

function summary(b: Book): string {
  return `${b.title} (${b.pages} pages)`;
}

const shelf: Book[] = [
  { title: "Dune", pages: 412 },
  { title: "Emma", pages: 474 },
];

shelf.forEach(b => console.log(summary(b)));
Output
Dune (412 pages)
Emma (474 pages)

A type alias doesn't create anything at runtime — it's purely a name for a type, erased during compilation. Aliases can name any type, not just objects:

TS other-aliases.ts
type ID = string | number;
type Point = [x: number, y: number];
type Callback = (error: Error | null) => void;

const userId: ID = 42;
const corner: Point = [0, 0];
const done: Callback = err => console.log(err ? "failed" : "ok");

done(null);
console.log(userId, corner);
Output
ok
42 [ 0, 0 ]

Optional and readonly properties

TS modifiers.ts
type Product = {
  readonly id: number;
  name: string;
  discount?: number;
};

const mug: Product = { id: 1, name: "Mug" };
console.log(mug.discount);

mug.id = 2;
tsc output
error TS2540: Cannot assign to 'id' because it is a read-only property.

discount? may be left out entirely; reading it then gives undefined, so its type is really number | undefined. readonly id can be set when the object is created but never reassigned.

Excess property checks

TypeScript checks shapes structurally: an object with extra properties is usually fine. But when you write an object literal directly where a type is expected, extra properties are flagged, because they're most likely typos:

TS excess.ts
type Options = { width: number; height?: number };

const opts: Options = { width: 100, hieght: 50 };
tsc output
error TS2561: Object literal may only specify known properties, but 'hieght' does not exist in type 'Options'. Did you mean to write 'height'?

The compiler even suggests the property you probably meant. This check only applies to fresh object literals. If the object is first stored in a variable and then passed along, the extra property is allowed — the value still has everything Options requires.

Nested objects

TS nested.ts
type Address = { city: string; postcode: string };
type Customer = {
  name: string;
  address: Address;
  tags: string[];
};

const c: Customer = {
  name: "Rosa",
  address: { city: "Porto", postcode: "4000" },
  tags: ["vip"],
};

console.log(`${c.name} lives in ${c.address.city}`);
Output
Rosa lives in Porto

Breaking a large shape into smaller named aliases like Address keeps each one readable and lets you reuse them independently.

Method properties

An object type can describe functions too, either as a property holding a function or with method syntax:

TS methods.ts
type Counter = {
  count: number;
  increment(): void;
  reset: () => void;
};

const counter: Counter = {
  count: 0,
  increment() { this.count++; },
  reset() { this.count = 0; },
};

counter.increment();
counter.increment();
console.log(counter.count);
Output
2

Try it yourself

Try it yourself
Console output
Coming next: interfaces are the other main way to name an object shape. The next lesson covers them and explains when to pick interface or type.