Augmenting third-party libraries in Typescript - Time & Space Complexity
When we add new features to existing third-party libraries, it is important to know how this affects the speed of our program.
We want to find out how the extra code changes the time it takes to run as the input grows.
Analyze the time complexity of the following code snippet.
// Adding a new method to a third-party library interface
declare module 'some-library' {
interface SomeInterface {
newMethod(): void;
}
}
// Implementation of the new method
SomeLibrary.SomeInterface.prototype.newMethod = function() {
for (let i = 0; i < this.items.length; i++) {
console.log(this.items[i]);
}
};
This code adds a new method to a library's interface that loops through an array and prints each item.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: A for-loop that goes through each item in an array.
- How many times: The loop runs once for every item in the array.
Explain the growth pattern intuitively.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 loops |
| 100 | 100 loops |
| 1000 | 1000 loops |
Pattern observation: The number of operations grows directly with the number of items. Double the items, double the work.
Time Complexity: O(n)
This means the time to run the new method grows in a straight line with the number of items.
[X] Wrong: "Adding a method like this does not affect performance because it's just extra code."
[OK] Correct: Even small added loops run more steps as input grows, so they do affect how long the program takes.
Understanding how your additions to existing code affect speed shows you can write code that stays fast and reliable as it grows.
"What if the new method called another method that also loops through the array? How would the time complexity change?"
Practice
Solution
Step 1: Understand the goal of augmentation
Augmentation is used to add or fix types in existing third-party libraries without modifying their source code.Step 2: Compare options with this goal
Only To add or fix types without changing the original library code matches this purpose. Other options describe different tasks unrelated to augmentation.Final Answer:
To add or fix types without changing the original library code -> Option AQuick Check:
Augmenting = add/fix types without code change [OK]
- Thinking augmentation rewrites library code
- Confusing augmentation with code conversion
- Assuming augmentation removes functions
my-lib?Solution
Step 1: Recall correct augmentation syntax
TypeScript usesdeclare module 'library-name' { }to augment modules.Step 2: Check options for this syntax
Only declare module 'my-lib' { } usesdeclare modulecorrectly. Others use invalid keywords.Final Answer:
declare module 'my-lib' { } -> Option DQuick Check:
Use declare module for augmentation [OK]
- Omitting the declare keyword
- Using wrong keywords like augment or extend
- Using module without declare
lodash library to add a new method double to its LoDashStatic interface?declare module 'lodash' {
interface LoDashStatic {
double(n: number): number;
}
}
import _ from 'lodash';
console.log(_.double(4));Solution
Step 1: Understand augmentation effect
Augmentation adds type info but does not add actual implementation code.Step 2: Analyze runtime behavior
Since_.doubleis not implemented, calling it causes a runtime error.Final Answer:
Runtime error: _.double is not a function -> Option AQuick Check:
Augmentation adds types only, no code [OK]
- Assuming augmentation adds implementation automatically
- Expecting TypeScript error instead of runtime error
- Confusing type addition with code addition
express that tries to add a new property userId to the Request interface:declare module 'express' {
interface Request {
userId: string;
}
}
// Usage
import express from 'express';
const app = express();
app.use((req, res, next) => {
console.log(req.userId);
next();
});Solution
Step 1: Check correct module for Request interface
In Express, theRequestinterface is declared in 'express-serve-static-core', not directly in 'express'.Step 2: Understand augmentation target
To augmentRequest, you must declare module 'express-serve-static-core', or augmentation won't apply correctly.Final Answer:
The module name should be 'express-serve-static-core' instead of 'express' -> Option CQuick Check:
Augment correct module name for interface [OK]
- Augmenting wrong module name
- Making property optional unnecessarily
- Thinking interface cannot be augmented
react-router-dom library to add a new optional property meta of type { requiresAuth: boolean } to the RouteProps interface. Which code snippet correctly achieves this and ensures TypeScript recognizes the new property?Solution
Step 1: Identify correct module to augment
TheRoutePropsinterface is declared in 'react-router-dom', so we must augment that module.Step 2: Write augmentation with optional property
Usedeclare module 'react-router-dom'and addmeta?: { requiresAuth: boolean }insideRouteProps.Final Answer:
declare module 'react-router-dom' { interface RouteProps { meta?: { requiresAuth: boolean }; } } -> Option BQuick Check:
Augment correct module with optional property [OK]
- Augmenting wrong module name
- Not using declare module syntax
- Adding property outside interface
Ready to prove it?
Pass the test and this pattern moves unknown
