ProgrammingFullstack Developer

How to implement and type a function with destructuring of nested parameters in TypeScript? What are the nuances of using default values, optional, and required properties?

Pass interviews with Hintsage AI assistant

Answer.

Background: In JavaScript, functions often use object destructuring directly in the signature. In TypeScript, this approach requires a clear description of the structure of the destructured parameters and the setting of default values; otherwise, there may be errors when accessing non-existent properties and incorrect type inference.

Problem: It is not obvious how to correctly describe the type of the entire parameter or individual nested properties in the destructured object, especially when there are optional and nested fields, as well as default values.

Solution: Always describe a separate type or interface for the structure of function parameters, explicitly indicate which fields are required, which are optional, and set default values in the body of the function or directly in the parameters using ES6 syntax.

Code example:

interface UserOptions { name: string; age?: number; address?: { city: string; zipcode?: string }; } function registerUser( { name, age = 18, address = { city: 'Unknown' } }: UserOptions ): string { return `${name}, ${age}, ${address.city}`; }

Key features:

  • For destructuring nested parameters, always use an interface or type.
  • Set default values for fields in the function signature.
  • For optional properties (age?, address?), always think through scenarios where they might be absent.

Trick questions.

Can you omit the type description of the parameter object, relying on automatic inference?

No, this is dangerous. If you do not specify the type UserOptions, the compiler will not indicate required properties, default values will not be captured for nested fields, and implicit errors will occur during use.

function example({ x, y }) { ... } // x and y — any

How to set a default value for a nested object while partially overriding properties?

Use spread. However, spread does not "glue" types if the type address is optional. You need to perform a check or explicitly set a default.

function fn({ obj = { foo: 1 } }: { obj?: { foo: number } }) { const address = { foo: 42, ...obj }; }

What is the danger of destructuring with optional fields without defaults?

If you omit a default for optional properties, accesses to properties (e.g., address.city) may lead to runtime errors. It is better to explicitly set ? and a default.

function danger({ address }: { address?: { city: string } }) { console.log(address.city); // Error, address may be undefined }

Common errors and anti-patterns

  • Implicit typing of destructured arguments (any)
  • Lack of defaults for nested/optional properties
  • Not using interfaces and type aliases for structural parameters

Real-life example

Negative case

In old code, the parameter object was destructured without explicit typing. When a new field was added to the function, all places of use were not automatically found, breaking calls in production.

Pros:

  • Fast and easy to write

Cons:

  • Lack of safety and control over structure
  • Fragility during changes

Positive case

Implemented interfaces for all such functions, covered scenarios with undefined and default values with tests, and the compiler's hints allowed easy mass changes.

Pros:

  • High type safety
  • Ease of refactoring and scaling

Cons:

  • Slightly more text in type declarations