Skip to content

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.

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.

Guard Location Checks if
isPayloadMedia src/guards/payload-objects.ts Value is a Media object (not just an ID)
isPopulated src/guards/payload-objects.ts Relation is a populated document (not just an ID)
isNonEmptyArray src/guards/array.ts Array has at least one item
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
}
typeof value === 'string' // Check primitive type
'property' in value // Check property exists
typeof value === 'object' && value !== null // Safe object check
Array.isArray(value) // Array check
  • 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