At first glance, union types don't seem very useful. If we have a variable of type `User | User[]`, there's not much we can do with it. We can't treat it like a single `User` because it might be a `User[]`. But we also can't treat it like a `User[]` because it might be a single `User`. We get around this by handling both possibilities in our code. For example: if we're passed one user, we return their name. If we're passed an array of users, we return its length. ```ts type User = { name: string }; function nameOrLength(userOrUsers: User | User[]) { if (Array.isArray(userOrUsers)) { // Inside this side of the if, userOrUsers' type is User[]. return userOrUsers.length; } else { // Inside this side of the if, userOrUsers' type is User. return userOrUsers.name; } } nameOrLength({name: 'Amir'}) //➞ 'Amir' nameOrLength([{name: 'Amir'}, {name: 'Betty'}]) //➞ 2 ``` `userOrUsers` is a `User | User[]`. Why are we allowed to access its `length` and its `name` here? Arrays don't have a `name`, and `User`s don't have a `length`. ```ts const userOrUsers: User | User[] = [{name: 'Amir'}]; userOrUsers.name //➞ type error: Property 'name' does not exist on type 'User[]' ``` ```ts const userOrUsers: User | User[] = {name: 'Amir'}; userOrUsers.length //➞ type error: Property 'length' does not exist on type 'User' ``` The answer is that TypeScript can see our `if (Array.isArray(userOrUsers))` check. If `Array.isArray` is true, then the type can only be `User[]`, not `User`. The TypeScript compiler knows what `Array.isArray` means when used in a conditional. The same logic applies to "else" side of the conditional. On that side, `Array.isArray(userOrUsers)` is false, so it must be a single `User`, not a `User[]`. In both cases, we say that we've _narrowed_ the type. We've taken a wide type like `User | User[]` and reduced it to a narrower type like `User` or `User[]`. The `Array.isArray` function is a _type guard_. When used inside an `if` or other conditional, a _type guard_ makes a guarantee about the type. It "guards" the code inside the conditional, ensuring that it only executes for certain types.