# Type Guards — TypeScript

Source: https://www.geekswithgeeks.com/en/typescript/ts-type-guards

> Narrow a broad type down to a specific one using runtime checks.

## typeof narrowing

Inside an `if (typeof x === "string")` block, TS knows `x` is a `string` for the rest of that branch.

```typescript
function printId(id: string | number) {
  if (typeof id === "string") {
    console.log(id.toUpperCase()); // id is string here
  } else {
    console.log(id.toFixed(2));    // id is number here
  }
}
```

## instanceof narrowing

For classes, `instanceof` narrows a union of class types down to the matching one.

```typescript
class Cat { meow() { return "Meow!"; } }
class Dog { bark() { return "Woof!"; } }

function speak(pet: Cat | Dog) {
  if (pet instanceof Cat) {
    console.log(pet.meow());
  } else {
    console.log(pet.bark());
  }
}
```

## Why narrow at all?

A union type only exposes the properties **common to every member**. Narrowing proves to the compiler which member you actually have, unlocking its specific properties and methods.

**Quiz:** Inside `if (typeof id === "string") { ... }`, what type does TS assign to `id`?

- [ ] string | number, unchanged
- [x] string
- [ ] any

*Answer:* string. The typeof check narrows the union to just string inside that block.
