Instructor: Let's say I have two interfaces, one for admin and another for a normal user. I have a function, redirect, that accepts an object as an argument that can be either an admin or a user.
Now, if the user is an admin, I want to redirect to a specific route on my page and pass in this admin-only property. Otherwise, I want to use the normal route and pass in just the email, which is a user-only property.
Now, what can we write in here to have it pass only if the user is an admin? We can ask TypeScript to assume that the user is an admin and then check if a specific admin-only property is defined on it -- in this case, the role.
Even though we can tell visually that this line of code will only get executed if the user is an admin, TypeScript can't make that inference and it's throwing an error here because it still can't be sure that our object is an admin. It thinks it might still be a user, and users don't have a role property on them.
I can also create a custom type guard right below here. If this returns true, then the user is an admin. That fix our problem.
If I hover over user in this context, you can see TypeScript knows it's an admin. But that might become a bit too much if we start creating these functions every time we need TypeScript to infer types based on simple properties.
Since TypeScript 2.7, the compiler will now start to infer the type of an object in a block that wraps a condition containing the in operator. In this case, TypeScript will essentially think, "OK, so my input can only be of type admin or user."
If it passes that if condition, that means it has the role property on it. Out of admin and user, the only type that includes the role property is admin. That means in this block it must be admin. We can confirm that by hovering over it.
This is great. All of the errors went away now, both in the first block and in the second else block. If I want to use user for something else here, you can see I only get suggestions for admin properties, which is ID and role.
Also, because I marked my argument as either an admin or a user, and since we confirmed that if it goes in the if block it's an admin, that means that it's only going to go in the else block if it's a user.
We can confirm this by trying to access some properties on it. We can see that I now only get user properties. I only get email. TypeScript will keep doing this intelligent inference in all of our logic branches.