Generic class syntax in Typescript - Time & Space Complexity
We want to understand how the time it takes to run a generic class changes as we use it with different amounts of data.
How does the size of the input affect the work done inside the generic class?
Analyze the time complexity of the following code snippet.
class Box<T> {
items: T[] = [];
add(item: T) {
this.items.push(item);
}
get(index: number): T | undefined {
return this.items[index];
}
}
This code defines a generic class that stores items and allows adding and retrieving them by index.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Adding an item to the array using push.
- How many times: Once per add call, no loops inside add or get methods.
Explain the growth pattern intuitively.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 push operations |
| 100 | 100 push operations |
| 1000 | 1000 push operations |
Pattern observation: Each add call does a simple push, so operations grow directly with the number of items added.
Time Complexity: O(n)
This means the time to add n items grows in a straight line with n; doubling items roughly doubles the time.
[X] Wrong: "Using a generic class makes operations slower because of extra type handling."
[OK] Correct: Generics in TypeScript are erased at runtime, so they do not add extra time cost to operations.
Understanding how generic classes behave helps you explain how your code scales and stays efficient when handling different data types.
"What if the add method searched for duplicates before adding? How would the time complexity change?"
Practice
<T> mean in a TypeScript generic class declaration like class Box<T> {}?Solution
Step 1: Understand generic type parameter
The<T>after the class name declares a generic type parameter named T, which acts as a placeholder for any type.Step 2: Purpose of generic classes
This allows the class to work flexibly with any type specified when creating an instance, making the code reusable and type-safe.Final Answer:
It declares a placeholder type that can be replaced with any type when creating an instance. -> Option AQuick Check:
Generic <T> = placeholder type [OK]
- Thinking <T> fixes the type permanently
- Confusing generic syntax with inheritance
- Assuming <T> is a variable or value
Container with a type parameter T?Solution
Step 1: Recall generic class syntax
In TypeScript, generic classes use angle brackets<>to declare type parameters after the class name.Step 2: Match correct syntax
The correct syntax isclass Container<T> {}. Other options use parentheses, curly braces, or square brackets incorrectly.Final Answer:
class Container<T> {} -> Option DQuick Check:
Generic class uses <T> syntax [OK]
- Using parentheses instead of angle brackets
- Placing type parameter inside class body
- Using square brackets which are for arrays
class Box<T> {
content: T;
constructor(value: T) {
this.content = value;
}
getContent(): T {
return this.content;
}
}
const box = new Box<string>('hello');
console.log(box.getContent());Solution
Step 1: Understand class instantiation
The classBox<T>is instantiated withT = string, socontentis a string holding 'hello'.Step 2: Trace method call
The methodgetContent()returns the storedcontent, which is 'hello'. The console.log prints this string.Final Answer:
hello -> Option CQuick Check:
Generic class returns stored value 'hello' [OK]
- Expecting object print instead of string
- Confusing property with method output
- Thinking generic causes runtime error
class Pair<T, U> {
first: T;
second: U;
constructor(first: T, second: T) {
this.first = first;
this.second = second;
}
}Solution
Step 1: Compare constructor parameters with property types
The class declares two generic typesTandU, with propertiesfirst: Tandsecond: U.Step 2: Identify mismatch in constructor
The constructor incorrectly usessecond: Tinstead ofsecond: U, causing a type mismatch.Final Answer:
Constructor parameters should be (first: T, second: U) to match property types. -> Option AQuick Check:
Constructor params must match generic property types [OK]
- Using same type for both parameters ignoring generics
- Removing one generic parameter incorrectly
- Thinking constructor can't have parameters in generics
Dictionary<K, V> that stores key-value pairs. Which implementation correctly uses generics to store and retrieve values by key?class Dictionary<K, V> {
private items: Map<K, V> = new Map();
add(key: K, value: V): void {
this.items.set(key, value);
}
get(key: K): V | undefined {
return this.items.get(key);
}
}Solution
Step 1: Analyze Map usage with generics
The class usesMap<K, V>to store keys of type K and values of type V, which is correct.Step 2: Check methods for correct generic usage
Theaddmethod sets a key-value pair, andgetretrieves the value by key, both using the generic types properly.Final Answer:
This implementation correctly uses generics to store and retrieve values by key. -> Option BQuick Check:
Generic Map<K, V> with add/get methods = correct [OK]
- Swapping key and value types in Map declaration
- Expecting add to return a value unnecessarily
- Believing generics can't be used with built-in types
Ready to prove it?
Pass the test and this pattern moves unknown
