DevAcademy
LearnTypeScriptObject Types
IntermediateTypeScript

Object Types

Learn how to type object shapes inline, nested objects, and index signatures for dynamic keys.

Reading Time

14 min

Lesson

Lesson 13 of 30

Inline Object Types

An object’s shape can be typed directly inline, without a separate interface or type alias — useful for small, one-off shapes.

Inline Object Type

function printCoordinate(point: { x: number; y: number }) {
  console.log(`(${point.x}, ${point.y})`);
}

printCoordinate({ x: 10, y: 20 });

Nested Object Types

Object types can be nested to describe deeply structured data, mirroring the shape of the actual object.

Nested Objects

interface Order {
  id: number;
  customer: {
    name: string;
    email: string;
  };
  total: number;
}

const order: Order = {
  id: 1,
  customer: { name: "Alice", email: "alice@example.com" },
  total: 49.99,
};

Index Signatures

An index signature types an object whose exact keys aren’t known ahead of time, but whose values all share a common type — like a dictionary or lookup table.

Index Signature

interface Scores {
  [studentName: string]: number;
}

const scores: Scores = {
  Alice: 92,
  Bob: 88,
};

scores.Charlie = 95; // OK — any string key maps to a number

Record<K, V> as an Alternative

The built-in Record<K, V> utility type is a more concise, commonly preferred way to type a dictionary object with known key types.

Record Utility Type

type Scores = Record<string, number>;

const scores: Scores = {
  Alice: 92,
  Bob: 88,
};

Excess Property Checks

When passing an object literal directly where a specific type is expected, TypeScript performs an extra check and flags properties that don’t exist on the target type — a safeguard against typos.

Excess Property Check

interface Config {
  timeout: number;
}

function setup(config: Config) {}

setup({ timeout: 1000, timeOut: 2000 }); // Error: 'timeOut' does not exist on type 'Config'

Excess Checks Only Apply to Object Literals

Assigning through a variable instead of a literal skips this check, since the variable might legitimately have extra properties from a wider type — this is a deliberate part of structural typing.

Best Practice

Use Record<K, V> for simple dictionaries with known key/value types, and reach for a full interface once the object has several distinct, individually meaningful properties.

Interview Questions

Quick Quiz

1. What is an index signature used for?

2. What does Record<string, number> describe?

3. When does TypeScript perform excess property checks?