Skip to content

fieldValidator

fieldValidator<TCollectionSlug, TValue, TField>(slug, fn): FieldValidate<TCollectionSlug, TValue>

Defined in: packages/core/src/fields/baseTypes.ts:171

Types a field’s validate() against a real collection, DataModel, and field config, without threading generics through the field factory (text<Meta, "posts">(...), which also forces you to spell out TFieldMeta). TCollectionSlug is inferred from slug; supply TValue/TDataModel/TField explicitly for a typed value/ctx/field.

Each field type builds its own narrower wrapper on top of this — e.g. textValidator (fields/text/validator.ts) pins TValue to string and TField to TextField — so authoring a field’s validate never needs TValue/TField spelled out by hand.

TCollectionSlug extends string

TValue = unknown

TField = unknown

TCollectionSlug

The collection slug doc should be typed as — pass the same constant the collection itself is defineCollection({ slug })-ed with (e.g. TABLE_SLUG_PAGES), not a fresh string literal, so a rename of one renames the other.

FieldValidate<TCollectionSlug, TValue, TField>

The validate function, checked against the real types.

FieldValidate<TCollectionSlug, TValue>

The same function, re-typed to the field’s loose public validate signature.

import { ConvexError } from "convex/values"
slug: text({
validate: textValidator<typeof TABLE_SLUG_PAGES>(
TABLE_SLUG_PAGES,
async ({ value, doc, ctx, field }) => {
const existing = await ctx.db
.query("pages")
.withIndex("by_slug", (q) => q.eq("slug", value))
.first();
if (existing && existing._id !== doc._id) {
throw new ConvexError({ message: `${field.label} must be unique.` });
}
},
),
})