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:
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 }
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:
Cons:
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:
Cons: