TypeScript · Modelling Data

Objects and Type Aliases

Most data in real apps is objects — users, products, orders. A type alias gives a shape a name so you can reuse it everywhere.

Beginner 5 min Lesson 7 of 29Examples target TypeScript 5.x with "strict": true.
Before you start:Basic Types
0/29 in TypeScript
On this page · 5 min · Beginner

Learning objectives#

  • Write inline object types
  • Name shapes with type aliases
  • Use optional (?) and readonly properties
  • Describe dictionaries with index signatures and Record

Explanation#

An object type lists properties and their types: { name: string; age: number }.

type User = { … } creates a reusable name (an alias). Aliases can name any type, not just objects: type ID = string | number.

Optional properties end with ?: bio?: string means bio can be missing (its type becomes string | undefined).

readonly id: number forbids changing that property after creation.

For objects with unknown keys use an index signature { [key: string]: number } or the simpler Record<string, number>.

TypeScript is structural: any object with the right shape fits the type, regardless of how it was created. Extra properties are flagged only on fresh object literals.

Syntax#

TypeScript Illustrative
type Product = {
  readonly id: number;
  name: string;
  description?: string;
};

Code example: Modelling a product catalogue#

TypeScriptModelling a product catalogue Illustrative
type ID = number;


type Price = {
  amount: number;
  currency: 'INR' | 'USD';
};


type Product = {
  readonly id: ID;
  name: string;
  price: Price;            // nested type
  description?: string;    // optional
  tags: string[];
};


const kurta: Product = {
  id: 1,
  name: 'Cotton Kurta',
  price: { amount: 799, currency: 'INR' },
  tags: ['clothing'],
};


kurta.id = 2;                         // ✗ Cannot assign to 'id' because it is a read-only property
kurta.description?.toUpperCase();    // ✓ safe: description may be undefined


const stock: Record<string, number> = { kurta: 12, saree: 4 };
stock['dupatta'] = 7;                 // ✓ any string key


const bad: Product = { id: 3, name: 'Cap', price: { amount: 99, currency: 'INR' }, tags: [], colour: 'red' };
//                                                                                           ~~~~~~
// ✗ Object literal may only specify known properties, and 'colour' does not exist in type 'Product'
Expected output
Two errors: changing the read-only id and the unknown colour property. The optional description is handled safely with ?.

This example is illustrative. Copy or download it and run it in your own environment; the expected output is shown above.

Step-by-step explanation#

  1. type ID = number is an alias for a primitive, making intent clear.
  2. Price is used inside Product — types compose.
  3. readonly id cannot be reassigned.
  4. description? may be missing, so we access it with ?.
  5. Record<string, number> describes a dictionary of counts.
  6. A typo-like extra property on a literal is reported.

Real-world use case#

API response models, Redux state, form values and database rows are all described with object types and aliases shared across the app.

Common mistakes#

Making everything optional

If every property has ?, you must check everything everywhere. Only mark truly optional fields.

Thinking readonly is deep

readonly items: string[] stops reassigning items, but items.push still works. Use readonly string[] too.

Using object or {} as a type

{} means “anything except null/undefined”. Describe the real shape instead.

Best practices#

  • Name every shape you use more than once
  • Use readonly for ids and data you must not change
  • Prefer Record<K, V> over hand-written index signatures
  • Keep types next to the code that owns them, or in a types.ts file

Remember this#

type Name = shape → a reusable label for a type.

? = may be missing. readonly = can’t change after creation.

Fits the shape → fits the type (structural typing).

Practice exercise#

Your task: Create a type Address (street, city, pin, optional landmark) and a type Customer with a readonly id, name and an array of addresses.

Need a hint?
Nest Address[] inside Customer.
Show solution
TypeScript Illustrative
type Address = {
  street: string;
  city: string;
  pin: string;
  landmark?: string;
};


type Customer = {
  readonly id: number;
  name: string;
  addresses: Address[];
};

Mini quiz#

Objects and Type Aliases quizMultiple choice Question 1 of 3

What does age?: number mean?

Score so far: 0/0

Want more? Practise all TypeScript MCQs · TypeScript interview questions

My notes#

Saved in this browser.

Progress is saved in this browser. Sign in to sync.