TypeScript recognizes several JavaScript runtime checks as narrowing guards: `typeof` for primitives, `in` for property existence, and `instanceof` for class instances.
ts
function format(value: string | number): string {
if (typeof value === "number") return value.toFixed(2);
return value.toUpperCase();
}
interface Dog { bark(): void; }
interface Cat { meow(): void; }
function speak(a: Dog | Cat) {
if ("bark" in a) a.bark();
else a.meow();
}
class ApiError extends Error {}
function handle(e: Error) {
if (e instanceof ApiError) console.log("api error");
}Each branch narrows the variable's static type to match the runtime check, so property/method access inside the branch is fully type-checked against the narrower type.