Hone logo
Hone
Problems

Mastering Declaration Merging in TypeScript

Declaration merging is a powerful feature in TypeScript that allows you to combine multiple declarations of the same name into a single definition. This is particularly useful for extending existing types, adding properties to built-in JavaScript objects, or integrating with third-party libraries. This challenge will test your understanding of how to effectively use declaration merging to enhance type safety and code organization.

Problem Description

Your task is to implement declaration merging in TypeScript in two distinct scenarios:

  1. Extending Built-in JavaScript Objects: You need to add a new method to the String prototype, making it accessible on all string instances.
  2. Augmenting Third-Party Library Interfaces: You will simulate augmenting an interface from a hypothetical third-party library to add new properties.

You should demonstrate your ability to:

  • Declare new members (methods, properties) for existing JavaScript global objects.
  • Augment existing interfaces by adding new properties.
  • Ensure that the merged declarations are correctly typed and usable.

Key Requirements:

  • String Extension: Implement a method named reverseString on String.prototype that returns a reversed version of the string it's called on.
  • Interface Augmentation: Create an interface named UserConfig (assume it's defined elsewhere in a library) and then augment it to add a new optional property called themeColor of type string.
  • Demonstrate Usage: Provide clear examples showing how to use both the extended string method and the augmented interface.

Expected Behavior:

  • Calling .reverseString() on any string literal or string variable should return the reversed string.
  • Instances of a type that implements UserConfig should be able to optionally include a themeColor property.

Examples

Example 1: String Extension

// Assume this is how you'd use it
const originalString = "TypeScript";
const reversedString = originalString.reverseString();
console.log(reversedString); // Expected: "tpircSepyT"

Example 2: Interface Augmentation

// Assume UserConfig is imported from a library
// declare module 'my-config-library' {
//   interface UserConfig {
//     userId: number;
//     // other properties...
//   }
// }

interface UserConfig {
    userId: number;
    // other properties...
}

// Your augmentation here
const user1: UserConfig = {
    userId: 123,
    themeColor: "blue"
};

const user2: UserConfig = {
    userId: 456
};

console.log(user1.themeColor); // Expected: "blue"
console.log(user2.themeColor); // Expected: undefined

Constraints

  • Your solution must be written entirely in TypeScript.
  • You should not modify the original JavaScript String prototype or any hypothetical library code directly. Instead, use TypeScript's declaration merging features.
  • The themeColor property for UserConfig should be optional.

Notes

  • To extend built-in JavaScript objects, you'll need to use a declaration file (.d.ts) or declare the augmentation within a global scope.
  • For interface augmentation, ensure you're targeting the correct interface name.
  • Think about how TypeScript's type system allows you to "see" and interact with these merged declarations.
Loading editor...
typescript