1. Welcome and Icebreaker:
- If you could transform or filter any set of data in your life, what would you change?
2. Outline the Session:
- We’ll revisit conditional and mapped types for more complex transformations.
- Learning Outcomes: Understand how to create advanced type logic using conditional and mapped types.
- Let’s get advanced!
3. Concept Explanation:
- Conditional Types can be nested and combined for complex logic.
- Mapped Types can use modifiers and remap keys.
- You can create utility types like
Partial, Required, Readonly, Pick, Omit, and more.
- Example:
type MyPartial<T> = { [K in keyof T]?: T[K] };
type MyOmit<T, K extends keyof T> = { [P in keyof T as Exclude<P, K>]: T[P] };
4. Live Coding Demonstration:
type User = { id: number; name: string; email?: string };
type RequiredUser = { [K in keyof User]-?: User[K] };
type UserWithoutEmail = Omit<User, "email">;
type IsString<T> = T extends string ? true : false;
type OnlyStrings<T> = { [K in keyof T as T[K] extends string ? K : never]: T[K] };
type StringProps = OnlyStrings<User>; // { name: string; email?: string }
// Nested conditional types
type DeepPartial<T> = {
[K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
};
const partialUser: DeepPartial<User> = { name: "Alice" };
5. Tasks:
- Short Exercise:
- Write a mapped type
Optional<T> that makes all properties optional.
- Write a conditional type
IsArray<T> that is true if T is an array, otherwise false.
- Create a type that picks only the string properties from an object type.