What if you could build any object with just one simple tool, no matter how many types you need?
Why Generic factory pattern in Typescript? - Purpose & Use Cases
Imagine you need to create many different types of objects in your program, like cars, bikes, and trucks. You write separate code for each type, repeating similar steps over and over.
This manual way is slow and boring. If you want to add a new type, you must write new code from scratch. It's easy to make mistakes and hard to keep track of all the different creation steps.
The generic factory pattern lets you write one smart piece of code that can create any type of object you want. You just tell it what type to make, and it handles the rest. This saves time and keeps your code clean and easy to change.
function createCar() { return new Car(); }
function createBike() { return new Bike(); }function create<T>(type: { new(): T }): T { return new type(); }It makes your code flexible and ready to build many kinds of objects without rewriting creation logic each time.
Think of a toy factory that can switch between making dolls, cars, or robots just by changing a setting, instead of building a new machine for each toy.
Manual object creation repeats code and wastes time.
Generic factory pattern creates any object type with one flexible function.
This approach makes adding new types easy and your code cleaner.
Practice
What is the main purpose of the Generic factory pattern in TypeScript?
Solution
Step 1: Understand the pattern's goal
The generic factory pattern is designed to create objects without needing to know their exact class ahead of time.Step 2: Compare options with the pattern's purpose
To create objects without specifying their exact class. correctly states this purpose. Other options describe unrelated features.Final Answer:
To create objects without specifying their exact class. -> Option BQuick Check:
Generic factory pattern = create objects flexibly [OK]
- Confusing with async handling
- Thinking it enforces variable typing
- Assuming it optimizes runtime speed
Which of the following is the correct syntax to declare a generic factory function in TypeScript?
function create<T>(): T { /* ... */ }Solution
Step 1: Analyze generic function syntax
The function declares a generic typeTand returns an object of typeT.Step 2: Check return statements for correctness
function create<T>(): T { return {} as T; } uses a type assertion{} as Twhich is valid to create a generic placeholder object. function create<T>(): T { return new T(); } tries to usenew T()which is invalid becauseTis a type parameter, not a constructor. function create<T>(): T { return T(); } callsT()like a function which is invalid. function create<T>(): T { return new Object(); } returns a generic object but not typed asT.Final Answer:
function create<T>(): T { return {} as T; } -> Option DQuick Check:
Generic factory syntax = use type assertion [OK]
- Trying to instantiate generic type with new
- Calling generic type as a function
- Returning untyped objects without assertion
What will be the output of this TypeScript code using a generic factory pattern?
interface Animal { speak(): string; }
class Dog implements Animal { speak() { return "Woof"; } }
function createAnimal<T extends Animal>(ctor: new () => T): T {
return new ctor();
}
const dog = createAnimal(Dog);
console.log(dog.speak());Solution
Step 1: Understand the factory function behavior
The functioncreateAnimaltakes a constructorctorand returns a new instance of typeTwhich extendsAnimal.Step 2: Trace the code execution
We passDogclass tocreateAnimal, so it returns a newDoginstance. Callingdog.speak()returns "Woof".Final Answer:
"Woof" -> Option AQuick Check:
Generic factory creates Dog, speak() = "Woof" [OK]
- Assuming generic type can't be instantiated
- Confusing type constraints with runtime errors
- Expecting undefined instead of method return
Identify the error in this generic factory function and select the fix.
function createInstance<T>(): T {
return new T();
}Solution
Step 1: Identify why
TypeScript does not allownew T()causes errornew T()becauseTis a type parameter, not a constructor function.Step 2: Apply correct fix using constructor parameter
Passing a constructor functionctor: new () => Tallows callingnew ctor()to create an instance ofT.Final Answer:
Add a constructor parameter:ctor: new () => Tand returnnew ctor(). -> Option AQuick Check:
Generic factory needs constructor parameter [OK]
- Trying to instantiate generic type directly
- Removing new keyword incorrectly
- Changing return type to any loses type safety
You want to create a generic factory that can produce different shapes with a draw() method. Which approach correctly uses the generic factory pattern to support adding new shapes easily?
interface Shape { draw(): void; }
class Circle implements Shape { draw() { console.log("Circle"); } }
class Square implements Shape { draw() { console.log("Square"); } }
// What is the best factory implementation?Solution
Step 1: Understand the requirement for flexibility
The factory should create any shape implementingShapewithout hardcoding types.Step 2: Evaluate each option
function createShape(ctor: new () => T): T { return new ctor(); } uses a generic constructor parameter allowing easy addition of new shapes. function createShape(): Shape { return new Circle(); } always returns Circle, no flexibility. function createShape(type: string): Shape { if(type === 'circle') return new Circle(); else return new Square(); } uses string checks, less type-safe and harder to extend. function createShape<T>(): T { return {} as T; } returns an empty object cast toT, which is unsafe.Final Answer:
function createShape<T extends Shape>(ctor: new () => T): T { return new ctor(); } -> Option CQuick Check:
Generic factory with constructor param = flexible shape creation [OK]
- Hardcoding return types limits extensibility
- Using string type checks reduces type safety
- Casting empty objects loses real behavior
Ready to prove it?
Pass the test and this pattern moves unknown
