-
Section 1: Getting Started
-
Section 2: Basic Types
-
Section 3: Functions and Objects
-
Section 4: Advanced Types
-
Section 5: Object-Oriented TypeScript
-
Section 6: Working with Modules
-
Section 7: Tooling and Practice
-
Section 8: Type-Level Programming
-
Section 9: TypeScript with Backends
-
Section 10: Testing Typed Code
-
Section 11: Data Validation with Types
-
Section 12: Practical Projects
-
Section 13: Compiler Internals
-
Section 14: Configuration Deep Dive
-
Section 15: Enums, Symbols, and Special Types
-
Section 16: Working with Async Code
-
Section 17: TypeScript and the DOM
-
Section 18: Advanced Generics Practice
-
Section 19: Working with Third-Party Types
-
Section 20: Monorepo and Large-Scale Practices
-
Section 21: Common Pitfalls and Best Practices
-
Section 22: Interview Practice
-
Section 23: Handbook: Narrowing In Depth
-
Section 24: Handbook: Object Types In Depth
-
Section 25: Handbook: Classes In Depth
-
Section 26: Handbook: Modules In Depth
-
Section 27: Handbook: Declaration Files In Depth
-
Section 28: JSX and Namespaces
-
Section 29: Compiler Configuration Reference
-
Section 30: More Practice Exercises
-
Section 31: Handbook: Everyday Types Deep Dive
-
Section 32: Utility Types Full Reference
-
Section 33: Decorators Reference
-
Section 34: Mixins and Advanced OOP Patterns
-
Section 35: Iterators and Generators Typing
-
Section 36: More Type-Level Programming Practice
-
Section 37: TypeScript Ecosystem Tools
-
Section 38: TypeScript with Testing Frameworks
-
Section 39: TypeScript for Library Authors
-
Section 40: More Interview Practice
-
Section 41: Handbook: Functions In Depth
-
Section 42: Handbook: Type Manipulation Deep Dive
-
Section 43: More Real-World Patterns
-
Section 44: TypeScript Release Notes Highlights
-
Section 45: Final Practice and Review
131: Common TypeScript Interview Questions on Advanced Types
When you hit the "Advanced Types" portion of a TypeScript interview, the interviewer isn't just checking if you know the syntax. They're trying to see if you can think in transformations. Most developers use types as static labels, but advanced TypeScript is more like a functional programming language that runs during compilation.
Think of it like a high-end custom tailor. A basic tailor just sells you a suit off the rack (that's your standard interface User { name: string }). But a master tailor takes an existing garment and applies a set of transformation rules to it. They might say, "Take this existing suit, but make every single button gold," or "Check the customer's height: if they're over six feet, use the Long pattern; otherwise, use the Standard pattern." Finally, they might look at a piece of fabric and say, "I don't know what this is yet, but I'm going to examine the weave to figure out the material."
Here is how those tailor rules map directly to the advanced types you'll be grilled on:
- "Make every button gold" → Mapped Types. You take an existing type and transform every property in it.
- "If height > 6ft, use Long pattern" → Conditional Types. You use a ternary-like syntax to decide which type to return based on another type.
- "Examine the weave to find the material" → The
inferkeyword. You tell TypeScript to "guess" or extract a specific type from within another type.
Handling the "Transform this Shape" Question
You'll almost certainly get a question asking you to create a utility type that modifies another. The classic example is creating a type where all properties are optional and read-only. Don't just reach for Partial<T>; the interviewer wants to see if you can build it from scratch using a mapped type.
type ReadonlyPartial<T> = {
readonly [P in keyof T]?: T[P];
};
interface User {
id: number;
name: string;
email: string;
}
// Now we have a type where everything is optional AND immutable
const update: ReadonlyPartial<User> = { name: "Alex" };
// update.name = "Sam"; // Error! It's readonly.
I've seen candidates stumble here by forgetting the T[P] part. Remember: P in keyof T iterates through the keys, but T[P] is how you actually grab the value type associated with that key.
The Logic of Conditional Types and infer
This is where interviews get spicy. A common question is: "How do you extract the type of the value inside a Promise?" This is where infer comes in. You can't just "get" the inner type; you have to describe a pattern that TypeScript should match against.
type UnpackPromise<T> = T extends Promise<infer U> ? U : T;
type Result1 = UnpackPromise<Promise<string>>;// Result1 is string
type Result2 = UnpackPromise<number>; // Result2 is number
In plain English, this says: "If T extends a Promise, let's infer what's inside that Promise and call it U. If it does, return U. Otherwise, just give me T back." It's a pattern-matching exercise. If you can explain it as "pattern matching for types," you'll sound like a pro.
The Magic of Template Literal Types
Recently, interviewers have started asking about Template Literal Types. This is the ability to manipulate strings at the type level. A great real-world example is creating a type for CSS properties or API endpoints. I love these because they eliminate "magic strings" in your codebase.
type EventName = "click" | "hover" | "focus";
type OnEvent = `on${Capitalize<EventName>}`;
// Result: "onClick" | "onHover" | "onFocus"
interface EventHandler {
[K in OnEvent]?: (event: MouseEvent) => void;
}
Notice the Capitalize intrinsic type. TypeScript provides a few of these (Uppercase, Lowercase) that work exclusively with template literals. When you use these in an interview, it shows you're keeping up with the modern evolution of the language, not just relying on a course from 2018.
📋 Practical Task
Build a DeepRouteParameterExtractor
In many modern apps, we define routes as strings, but we want our type system to extract the parameters from those strings to ensure we aren't passing the wrong IDs to our navigation functions.
Your Challenge: Create a utility type called ExtractRouteParam. It should take a string literal type that follows the pattern "/user/:id" or "/post/:postId" and extract the name of the parameter (the part after the colon) as a string literal type.
Requirements:
- Use Template Literal Types to match the pattern
/:${infer Param}. - Use Conditional Types and the
inferkeyword to extract the parameter name. - If the string does not contain a parameter (e.g.,
"/home"), it should returnnever.
Test your solution with these cases:
type Case1 = ExtractRouteParam<"/user/:userId">; // Should be "userId"
type Case2 = ExtractRouteParam<"/blog/:slug">; // Should be "slug"
type Case3 = ExtractRouteParam<"/about">; // Should be never
There are no comments for now.