Learn: Advance Typescript - Part 1
Concept-focused guide for Advance Typescript - Part 1 (no answers revealed).
~6 min read

Overview
Welcome to our deep dive into advanced TypeScript concepts! In this article, we'll explore a range of powerful features and patterns that frequently arise in interviews and real-world TypeScript development. By the end, you'll have a stronger grasp of topics like conditional and mapped types, utility types, type inference, type narrowing, and more—enabling you to write safer, more expressive, and maintainable code.
Concept-by-Concept Deep Dive
Conditional Types and Type Inference (infer)
Conditional types in TypeScript allow you to create types that depend on a condition. They're written like T extends U ? X : Y, meaning: if type T extends type U, the result is type X; otherwise, it's type Y.
Using infer in Conditional Types
The infer keyword lets you introduce a new type variable within a conditional type. It’s often used to "pull out" or "infer" a type from a structure. For example, T extends (infer U)[] ? U : T means: if T is an array of something, extract the element type as U; otherwise, just use T.
How to Reason About It:
- Identify the shape you’re checking (
T extends (infer U)[]). - If
Tfits that pattern,Ubecomes the element type. - If not, fallback to the default.
Common Misconceptions:
- Thinking
infercan be used outside conditional types—it cannot. - Not realizing that
infercan extract types from functions, arrays, promises, etc.
Utility Types: Partial, Omit, ReturnType, keyof
TypeScript provides several built-in utility types to transform or extract information from other types.
Partial<T>, Omit<T, K>, and ReturnType<T>
Partial<T>: Makes all properties inToptional.Omit<T, K>: Constructs a type by picking all properties fromTexcept those inK.ReturnType<T>: Extracts the return type of a function type.
keyof and Mapped Types
The keyof operator yields a union of property names (as string or symbol types) for a given type. Mapped types, such as { [K in keyof T]: ... }, allow you to iterate over these keys and build new types.
Reasoning Steps:
- Use
keyofto get keys. - Use mapped types to transform each property.
- Use utility types to combine or exclude properties as needed.
Common Misconceptions:
- Confusing
PartialandOmit. - Forgetting that
Omitremoves properties, whilePartialmakes them optional.
Literal Types and as const
TypeScript lets you create types that represent exact values (literals), not just general types like string or number.
The as const Assertion
Using as const transforms an array or object into a "readonly" structure with exact literal types for its values, rather than widening them to string, number, etc.
Benefits:
- Preserves specific values for type safety (e.g., for discriminated unions or enums).
- Prevents mutation (readonly).
Common Misconceptions:
- Assuming
as constis just syntactic sugar—it actually changes the type shape.
Type Narrowing and Type Guards
Type narrowing is the process of refining a variable's type within a block of code, typically using typeof, instanceof, or custom type guard functions.
Custom Type Guards
A function returning a type predicate (e.g., arr is string[]) lets TypeScript know how to narrow types inside control flow. For example, you can check if a variable is an array of strings, and then safely treat it as such after the check.
How to Write:
- Return a boolean.
- Use a type predicate in the return type (
x is SomeType).
Common Misconceptions:
- Forgetting to use the
issyntax in the return type, which means TypeScript can't narrow the type for you.
Generic Constraints and Type Parameters
Generics allow you to write reusable, type-safe code. Sometimes you want to restrict the kinds of types that can be used as arguments—this is where constraints (extends) come in.
How to Use:
<T extends SomeType>restrictsTto types that satisfySomeType.- This enables access to specific properties or methods within the generic.
Common Pitfalls:
- Omitting constraints leads to errors when accessing properties that may not exist.
- Over-constraining generics can reduce flexibility.
Discriminated Unions and Exhaustiveness
Discriminated unions use a common literal property (like type: 'a' | 'b') to distinguish between shapes. Switch or if-else statements can then "narrow" the type based on this property.
Why This Matters:
- Allows TypeScript to infer and check which properties are safe to access.
- Enables exhaustive checking—if all cases are handled, the code is safer.
Misconceptions:
- Forgetting to handle all cases, which can lead to runtime bugs.
Worked Examples (generic)
Example 1: Inferring an Array's Element Type
Suppose you have:
type ExtractElement<T> = T extends (infer U)[] ? U : T;
type Result = ExtractElement<string[]>; // What is Result?
Process:
Tisstring[], which matches(infer U)[]withUasstring.- So,
Resultbecomesstring.
Example 2: Making All Properties Optional
Given:
interface User { id: number; name: string; }
type MaybeUser = Partial<User>;
Process:
MaybeUserhas bothidandname, but both are optional (id?: number; name?: string).
Example 3: Using as const for Precise Types
const directions = ['N', 'E', 'S', 'W'] as const;
Process:
- Without
as const,directions: string[]. - With
as const,directions: readonly ['N', 'E', 'S', 'W']—a tuple of exact string literals, readonly.
Example 4: Custom Type Guard
function isNumberArray(val: unknown): val is number[] {
return Array.isArray(val) && val.every(item => typeof item === 'number');
}
Process:
- Checks at runtime.
- If true, within this block, TypeScript knows
valis anumber[].
Common Pitfalls and Fixes
- Forgetting to Use Type Guards Properly: Without a correct return type like
x is SomeType, narrowing won't occur. - Using Utility Types Incorrectly: Mixing up
OmitvsPartial, or forgetting to specify which keys to omit. - Not Understanding
as const: Assuming it only makes arrays readonly, when it also fixes literal types. - Improper Generic Constraints: Omitting or over-constraining generics leads to errors or loss of flexibility.
- Misusing
keyofand Mapped Types: Not realizing thatkeyof Tonly covers known properties, or misapplying mapped type syntax. - Discriminated Unions: Not exhausting all cases when narrowing by a discriminant property.
Summary
- Conditional types and
inferhelp you extract types from structures and build flexible type logic. - Utility types like
Partial,Omit, andReturnTypeare essential for transforming and interrogating types. - The
as constassertion creates exact, readonly values and can improve type safety significantly. - Type guards and narrowing let you safely refine types at runtime, enabling more robust code.
- Use generic constraints to ensure generics behave predictably and safely.
- Mastering mapped types and
keyofunlocks advanced type transformations and filtering.
With these concepts, you’re well-prepared for advanced TypeScript challenges and real-world scenarios—both in codebases and interviews!
Join us to receive notifications about our new vlogs/quizzes by subscribing here!