Skip to main content
Practice Problems

Index signatures and index access types in TypeScript

Index Signatures

An index signature defines the type for dynamic keys in an object when you don't know all property names in advance.


Basic Syntax

typescript
interface StringMap { [key: string]: string; } const translations: StringMap = { hello: "привіт", goodbye: "до побачення", // Any string key with string value is allowed }; interface NumberMap { [key: string]: number; } const scores: NumberMap = { math: 95, english: 88, };

Index Signature with Known Properties

typescript
interface Config { name: string; // Known property version: number; // Known property [key: string]: string | number; // Dynamic properties (must be compatible) } const config: Config = { name: "MyApp", version: 1, apiUrl: "https://api.example.com", timeout: 5000, };

Record vs Index Signature

typescript
// Index signature interface Dict { [key: string]: number; } // Record utility type (equivalent) type Dict = Record<string, number>; // Record with specific keys type Scores = Record<"math" | "english" | "science", number>; // { math: number; english: number; science: number }

Index Access Types (Lookup Types)

Use T[K] syntax to look up a specific property type:

typescript
interface User { id: string; name: string; email: string; address: { city: string; zip: string; }; } type UserId = User["id"]; // string type UserEmail = User["email"]; // string type UserAddress = User["address"]; // { city: string; zip: string } type City = User["address"]["city"]; // string // Multiple keys type IdOrEmail = User["id" | "email"]; // string

Indexed Access with Arrays

typescript
const roles = ["admin", "editor", "viewer"] as const; type Role = typeof roles[number]; // "admin" | "editor" | "viewer" type FirstRole = typeof roles[0]; // "admin"

Dynamic Property Types

typescript
interface ApiResponses { "/users": { users: User[] }; "/posts": { posts: Post[] }; "/comments": { comments: Comment[] }; } function fetchData<T extends keyof ApiResponses>( endpoint: T ): Promise<ApiResponses[T]> { return fetch(endpoint).then(r => r.json()); } // Return type is inferred! const result = await fetchData("/users"); // { users: User[] }

keyof with Index Signatures

typescript
interface StringMap { [key: string]: string; } type StringMapKeys = keyof StringMap; // string | number // (number because JS converts numeric keys to strings) interface NumberKeyMap { [key: number]: string; } type NumberMapKeys = keyof NumberKeyMap; // number

Mapped Types with Index Access

typescript
// Make all properties nullable type Nullable<T> = { [K in keyof T]: T[K] | null; }; type NullableUser = Nullable<User>; // { id: string | null; name: string | null; ... }

Important:

Index signatures define types for dynamic object keys. Index access types (T["key"]) let you extract property types. Combined with keyof, generics, and mapped types, they enable powerful type-safe patterns for APIs, configurations, and data transformations.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?
Practice Problems