#Can we pass custom types on validator?

7 messages · Page 1 of 1 (latest)

sour wyvern
#

@sage edge Can we pass custom types on validator or do we have to stick to using .any()?

sage edgeBOT
#

Let me check the knowledge base for you. One moment! :books:

#

Yes, you can pass custom types on validators in Convex. If you have a more specific type than what you can express with Convex validators, you can document that at the type level in Convex by casting once in your schema definition.

For instance, if you have a type that you use to distinguish different strings, you might want to make sure you're passing just those types around. Here's an example:

type MyStringType = string & { __myStringType: never };

You can use this type for Convex by setting a field validator as v.string(). However, if you cast it in your schema definition, you'll get the types everywhere automatically:

import { defineSchema, defineTable } from "convex/server";
import { Validator, v } from "convex/values";

defineSchema({
  myTable: defineTable({
    myField: v.string() as Validator<MyStringType>
  })
)}

In this case, myField will be typed as MyStringType. When you have a query like:

const doc = ctx.db
  .query("myTable")
	.filter(q => q.eq(q.field("myField"), foo)
	.first();

You will have type hints that the parameter for foo needs to be of type MyStringType and you'll get type errors if your type doesn't match. You'll also see that doc.myField has the type MyStringType when you retrieve it.

For more details, you can refer to the Using branded types in validators (https://stack.convex.dev/using-branded-types-in-validators) section in the Convex documentation.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@sour wyvern kapa.ai is still learning and improving, please let us know how it did by reacting below

sour wyvern
#

@sage edge if I have a custom types like fro import type { EmailWebhookEvent } from '@clerk/backend'; can we use that in validator?

sage edgeBOT
#

Let me check the knowledge base for you. One moment! :books:

#

If you have a custom type from an external library, such as EmailWebhookEvent from @clerk/backend, you can't directly use it as a Convex validator because Convex validators are a specific set of functions provided by the Convex library for validating data.

However, you can create a Convex validator that matches the structure of your custom type. For example, if EmailWebhookEvent is an object with certain properties, you can create a Convex validator using v.object() and specify the validators for each property.

If you want to ensure that the data matches the EmailWebhookEvent type at the TypeScript level, you can cast the Convex validator to your custom type in your schema definition, similar to the example provided in the Using branded types in validators (https://stack.convex.dev/using-branded-types-in-validators) section of the Convex documentation.

Please note that this casting is only for TypeScript's static type checking and does not perform any runtime validation. The actual validation of the data is done by the Convex validator.

If you need more granular validation at runtime, you might want to consider using a library like Zod, as mentioned in the Discord support thread (https://discord.com/channels/1019350475847499849/1135657569910784080). Zod allows you to define complex validation schemas that can be used for runtime validation. You can then use a helper function to convert Zod validators into Convex validators, as described in the Using Zod with TypeScript for Server-side Validation and End-to-End Types (https://stack.convex.dev/typescript-zod-function-validation#can-i-use-zod-to-define-my-database-types-too) section of the Convex documentation.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: