Skip to main content
Argument and return value validators ensure that queries, mutations, and actions are called with the correct types of arguments and return the expected types of return values. This is important for security! Without argument validation, a malicious user can call your public functions with unexpected arguments and cause surprising results. TypeScript alone won’t help because TypeScript types aren’t present at runtime. We recommend adding argument validation for all public functions in production apps. For non-public functions that are not called by clients, we recommend internal functions and optionally validation. Example: Argument Validation

Adding validators

To add argument validation to your functions, pass an object with args and handler properties to the query, mutation or action constructor. To add return value validation, use the returns property in this object:
If you define your function with an argument validator, there is no need to include TypeScript type annotations! The type of your function will be inferred automatically. Similarly, if you define a return value validator, the return type of your function will be inferred from the validator, and TypeScript will check that it matches the inferred return type of the handler function. Unlike TypeScript, validation for an object will throw if the object contains properties that are not declared in the validator. If the client supplies arguments not declared in args, or if the function returns a value that does not match the validator declared in returns. This is helpful to prevent bugs caused by mistyped names of arguments or returning more data than intended to a client. Even args: {} is a helpful use of validators because TypeScript will show an error on the client if you try to pass any arguments to the function which doesn’t expect them.

Supported types

All functions, both public and internal, can accept and return the following data types. Each type has a corresponding validator that can be accessed on the v object imported from "bijection/values". The database can store the exact same set of data types. Additionally you can also express type unions, literals, any types, and optional fields.

Bijection values

Bijection supports the following types of values:

Unions

You can describe fields that could be one of multiple types using v.union:
For convenience, v.nullable(foo) is equivalent to v.union(foo, v.null()).

Literals

Fields that are a constant can be expressed with v.literal. This is especially useful when combined with unions:

Record objects

You can describe objects that map arbitrary keys to values with v.record:
You can use other types of string validators for the keys:
Notes:
  • This type corresponds to the Record<K,V> type in TypeScript.
  • You cannot use string literals as a record key.
  • Using v.string() as a record key validator will only allow ASCII characters.

Any

Fields that could take on any value can be represented with v.any():
This corresponds to the any type in TypeScript.

Optional fields

You can describe optional fields by wrapping their type with v.optional(...):
This corresponds to marking fields as optional with ? in TypeScript.

Extracting TypeScript types

The Infer type allows you to turn validator calls into TypeScript types. This can be useful to remove duplication between your validators and TypeScript types:

Reusing and extending validators

Validators can be defined once and shared between functions and table schemas.
You can create new object validators from existing ones by adding or removing fields using .pick, .omit, .extend, and .partial on object validators.
To validate whole documents of a table, use schema.doc(tableName), which is that table’s validator with the _id and _creationTime system fields added. schema.id(tableName) is v.id(tableName) restricted to the table names in your schema, for a type-safe alternative to v.id.
For a table defined with a union, schema.doc adds the system fields to each member of the union. Notes:
  • Object validators don’t allow extra properties, objects with properties that aren’t specified will fail validation.
  • Top-level table fields cannot start with _ because they are reserved for system fields like _id and _creationTime.