

0 / 2 embers
0 / 3000 xp
click for more info
Complete a lesson to start your streak
click for more info
Still calibrating
click for more info
Not enough gems
Cost: 6 gems
1: Conditional Types
incomplete
2: Infer
incomplete
3: Mapped Types
incomplete
4: Mapped Types With Conditionals
incomplete
5: Extracting Keys from Types
incomplete
Back
ctrl+,
Next
ctrl+.
This lesson's interactive features are locked, please to keep using them
We're now getting into some pretty advanced stuff that, while useful in really tricky modelling situations, is not something you'll need in application level code.
As a general rule, advanced TypeScript features are more useful in library code that needs to be more flexible, abstract, and reusable. Application level TypeScript code is generally much simpler and more concrete... grug make object type, grug use object type... grug happy.
Conditional types allow us to create new types based on conditions within the type system, they take this form:
type NewType = SomeType extends OtherType ? TrueType : FalseType;
It reads like a ternary expression: "If SomeType extends (satisfies) OtherType, then NewType is TrueType; otherwise, it's FalseType."
Here's a simple example:
type IsString<T> = T extends string ? true : false;
// Usage
type Result1 = IsString<"hello">; // true
type Result2 = IsString<42>; // false
type Result3 = IsString<string>; // true
In this example, IsString is a conditional type that checks if the type parameter T extends string. If it does, the resulting type is true; otherwise, it's false. TypeScript actually ships with some built-in conditional types:
type Extract<T, U> = T extends U ? T : never;type Exclude<T, U> = T extends U ? never : T;type NonNullable<T> = T extends null | undefined ? never : T;As usual, the question is, "when the heck is this useful???" Well, let's say we have some events that can fire in our front end application:
type ClickEvent = { type: "click"; x: number; y: number };
type KeyEvent = { type: "key"; key: string };
type MouseMoveEvent = { type: "mousemove"; x: number; y: number };
type FormEvent = { type: "submit"; formId: string };
type Event = ClickEvent | KeyEvent | MouseMoveEvent | FormEvent;
It may be useful to dynamically create a type that only includes "mouse-related" events: the ones that have an x and y property. We can use the Extract conditional type to do so:
// Extract is a TS built-in type, this is the implementation:
type Extract<T, U> = T extends U ? T : never;
// This is an example of how it can be used:
type MouseRelatedEvents = Extract<Event, { x: number; y: number }>;
Now MouseRelatedEvents is the same as:
type MouseRelatedEvents = ClickEvent | MouseMoveEvent;
The difference is that it's dynamic. If we add more events to the Event union, MouseRelatedEvents will automatically include them if they match the condition (i.e., if they have x and y properties).
Support.ai is experimenting with auto-replies – but only for tickets that seem emotionally safe.