How do you create a type-safe builder pattern in TypeScript?
Why Interviewers Ask This
Senior TypeScript engineers are expected to reason about architecture, performance, and edge cases. This question separates mid-level from senior candidates by testing deep system-level understanding.
Answer
A type-safe builder pattern uses TypeScript's type system to track what properties have been set and enforce that required properties are provided before the object is built. Using phantom types and conditional types: type HasName = { name: true }; type HasAge = { age: true }; class UserBuilder<T = {}> { private data: Partial<User> = {}; setName(name: string): UserBuilder<T & HasName> { this.data.name = name; return this as any; } setAge(age: number): UserBuilder<T & HasAge> { this.data.age = age; return this as any; } build(this: UserBuilder<HasName & HasAge>): User { return this.data as User; } }. With this, calling build() before setName() and setAge() is a compile-time error: new UserBuilder().setName("Alice").build(); — error, missing age. new UserBuilder().setName("Alice").setAge(30).build(); — valid. Each setter returns a more specific type that tracks progress, and build() requires the intersection of all required phantom types.
Common Mistake
A common mistake is memorizing definitions without understanding implications. When asked this question, go one level deeper — explain what happens when this concept is misused or ignored.
Previous
What is the accessor keyword in TypeScript 4.9?
Next
What is the performance impact of TypeScript and how can you optimize it?
More TypeScript Questions
View all →- Advanced What is structural typing in TypeScript?
- Advanced What are branded types (opaque types) in TypeScript?
- Advanced What is the Variance annotation in TypeScript 4.7?
- Advanced What is the satisfies operator used for in TypeScript?
- Advanced How do you implement a deep partial type in TypeScript?