

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: Narrowing Types
incomplete
2: Unknown Type
incomplete
3: Type Hierarchy
incomplete
4: Narrowing Using In
incomplete
5: Type Predicates
incomplete
6: Exhaustive Checks
incomplete
7: Guard Clauses
incomplete
8: Type Assertion
incomplete
9: Double Assertion
incomplete
10: Non-Null Assertion
incomplete
Back
ctrl+,
Next
ctrl+.
This lesson's interactive features are locked, please to keep using them
The in operator checks if a property exists in an object, which is fantastic for type narrowing in object literals.
type TextMessage = {
content: string;
sentAt: Date;
};
type ImageMessage = {
caption: string;
sentAt: Date;
};
type VideoMessage = {
duration: number;
sentAt: Date;
};
type Message = TextMessage | ImageMessage | VideoMessage;
function displayMessage(message: Message) {
if ("content" in message) {
// TypeScript knows this is a TextMessage
// because it's the only one with a 'content' property
console.log(`Text content is: ${message.content}`);
} else if ("caption" in message) {
// TypeScript knows this is an ImageMessage
// because it's the only one with an 'caption' property
console.log(`Image caption is ${message.caption}`);
} else {
// TypeScript knows this is a VideoMessage because
// it's the only other option
console.log(`Video length is ${message.duration}`);
}
}
You might have noticed that this kind of logic feels very similar to using discriminated unions, and you're correct. Here's the same types with an explicit discriminant property:
type TextMessage = {
kind: "text";
content: string;
sentAt: Date;
};
type ImageMessage = {
kind: "image";
caption: string;
sentAt: Date;
};
type VideoMessage = {
kind: "video";
duration: number;
sentAt: Date;
};
My recommendation is to prefer a discriminated union when you have full control of the types, but if you're using types from a library or package, or have another reason you don't want extra properties, the in operator is a great alternative.
Complete the processAttachment function. It should return a string based on the given Attachment, using the in operator to check the type: