ProgrammingBackend Developer

How to describe types for complex data structures (e.g., nested objects, arrays with different types) in TypeScript? What approaches are there and what common pitfalls are encountered? Provide practical examples.

Pass interviews with Hintsage AI assistant

Answer.

To describe complex data structures in TypeScript, interfaces (interface) and type aliases (type) are used. They can be combined with objects, arrays, and nested types for strict typing of complex collections.

For a nested object:

interface Address { city: string; zip: number; } interface UserProfile { name: string; age: number; address: Address; }

For an array with different types:

// Tuple let tuple: [string, number] = ['John', 30]; // Arrays with union types let arr: (string | number)[] = [1, 'a', 2, 'b']; // Array of objects let users: UserProfile[] = [ {...}, {...} ];

When structures are complex and there are optional fields, ? is used, combined with types like Partial, Record, Mapped Types, or recursive types for nested trees.

Trick question.

Question: Can an interface be used to describe an array with mixed elements (e.g., [string, number, boolean])?

Answer: No. For such cases, it is better to use tuples — interfaces are not suitable for fixed positions and types. Tuples allow you to strictly define types for each position.

type MyTuple = [string, number, boolean]; let foo: MyTuple = ['ok', 12, false];

Examples of real errors due to ignorance of the nuances of the topic.


Story

On a project, a complex structure was incorrectly described: for an array of mixed types, any[] was used instead of a valid tuple or union type. As a result, one of the elements contained a value of the wrong type, leading to an error in the business logic (arithmetic operation with a string).


Story

In the data structure, deeply nested objects were declared without using recursive types or Partial. The attempt to add a new subtree to a tree node caused a compiler error, and developers circumvented this through downcasting to any, which later caused runtime bugs in production.


Story

An object describing a user profile was partially optional, but the developer did not use ?. When receiving data from the server, TypeScript did not throw an error, but the application crashed when trying to access fields that did not exist in the object.