TypeScript
Beginner
1 min read
User-Defined Type Guards with is
Example
// User-defined type guard with 'is'
interface Cat { species: "cat"; meow(): void }
interface Dog { species: "dog"; bark(): void }
type Pet = Cat | Dog;
function isCat(pet: Pet): pet is Cat {
return pet.species === "cat";
}
function interact(pet: Pet): void {
if (isCat(pet)) {
pet.meow(); // TypeScript knows pet is Cat here
} else {
pet.bark(); // TypeScript knows pet is Dog here
}
}
// Validating unknown data from an API
interface ApiUser {
id: number;
name: string;
email: string;
}
function isApiUser(value: unknown): value is ApiUser {
return (
typeof value === "object" &&
value !== null &&
typeof (value as ApiUser).id === "number" &&
typeof (value as ApiUser).name === "string" &&
typeof (value as ApiUser).email === "string"
);
}
async function fetchUser(id: number): Promise<ApiUser> {
const response = await fetch(`/api/users/${id}`);
const data: unknown = await response.json();
if (!isApiUser(data)) throw new Error("Invalid user data from API");
return data; // narrowed to ApiUser
}
// Assertion function
function assertDefined<T>(val: T | null | undefined, msg: string): asserts val is T {
if (val == null) throw new Error(msg);
}
const element = document.getElementById("app");
assertDefined(element, "#app element not found");
element.innerHTML = "Hello"; // no null check needed
Related Resources
TypeScript Reference
Complete tag & property list
TypeScript How-To Guides
Step-by-step practical guides
TypeScript Exercises
Practice what you've learned
More in TypeScript