Type Guards
Type guards narrow TypeScript types at runtime, giving you safe access to properties without casting. This page covers the built-in guards and how to write your own.
What They Do
Section titled “What They Do”if (isMedia(image)) { // TypeScript knows: image is Media console.log(image.url);}Without the guard, TypeScript sees image as Media | number — Payload stores relations as either a populated object or a bare ID. The guard checks at runtime which one you actually have, and TypeScript narrows the type inside the if block so you can safely access .url.
Built-in Guards
Section titled “Built-in Guards”| Guard | Location | Checks if |
|---|---|---|
isPayloadImage | src/guards/payload-object.ts | Value is a Media object (not just an ID) |
isNonEmptyArray | src/guards/array.ts | Array has at least one item |
Creating a Guard
Section titled “Creating a Guard”export function isMedia(value: unknown): value is Media { return !!value && typeof value !== 'number' && 'url' in value;}The return type value is Media is what makes this a type guard — it tells TypeScript to narrow the type inside any if block that calls this function. The runtime check itself is plain JavaScript.
Template:
function isSomething(value: unknown): value is Something { return; // your runtime check}Common Checks
Section titled “Common Checks”typeof value === 'string' // Check primitive type'property' in value // Check property existstypeof value === 'object' && value !== null // Safe object checkArray.isArray(value) // Array checkUse Cases
Section titled “Use Cases”- Populated relations — Check whether a relation field is a full object or just an ID before accessing its properties
- API responses — Validate shape of incoming data at the boundary
- Component props — Safely handle fields that accept multiple types