Oscar
Oscar6d ago

Redundant typing

Hey noob question here I have a table definition here :
//schema.ts
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
import { authTables } from "@convex-dev/auth/server";

export default defineSchema({
...authTables,
users: defineTable({
name: v.string(),
email: v.string(),
phone: v.string(),
company: v.optional(v.string()),
createdAt: v.number(),
}).index("by_email", ["email"]),
orders: defineTable({
orderId: v.id("orders"),
clientEmail: v.string(),
price: v.number() ?? v.string(),
createdAt: v.number(),
}).index("by_user", ["orderId"]),
});
//schema.ts
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
import { authTables } from "@convex-dev/auth/server";

export default defineSchema({
...authTables,
users: defineTable({
name: v.string(),
email: v.string(),
phone: v.string(),
company: v.optional(v.string()),
createdAt: v.number(),
}).index("by_email", ["email"]),
orders: defineTable({
orderId: v.id("orders"),
clientEmail: v.string(),
price: v.number() ?? v.string(),
createdAt: v.number(),
}).index("by_user", ["orderId"]),
});
as you can see, I define the type of price here. In another file :
//orderFunctions.ts
import { mutation, query } from "./_generated/server";
import { v } from "convex/values";

export const addOrder = mutation({
args: {
clientEmail: v.string(),
price: v.optional(v.string() ?? v.number()),
},
handler: async (ctx, args) => {
const userId = await ctx.db.insert("orders", {
clientEmail: args.clientEmail,
price: args.price ?? "no price given",
createdAt: Date.now() ?? "no date given",
});
return userId;
},
});

export const getOrders = query({
args: {},
handler: async (ctx) => {
return await ctx.db.query("orders").collect();
},
});
//orderFunctions.ts
import { mutation, query } from "./_generated/server";
import { v } from "convex/values";

export const addOrder = mutation({
args: {
clientEmail: v.string(),
price: v.optional(v.string() ?? v.number()),
},
handler: async (ctx, args) => {
const userId = await ctx.db.insert("orders", {
clientEmail: args.clientEmail,
price: args.price ?? "no price given",
createdAt: Date.now() ?? "no date given",
});
return userId;
},
});

export const getOrders = query({
args: {},
handler: async (ctx) => {
return await ctx.db.query("orders").collect();
},
});
As you can see I am also defining types of args here, and setting values accordingly in "insert" part. My question is : since I'm already defining types when doing the tables, can I use these types in the args ? so that I don't have to copy/paste types between table and args ?
5 Replies
Convex Bot
Convex Bot6d ago
Thanks for posting in <#1088161997662724167>. Reminder: If you have a Convex Pro account, use the Convex Dashboard to file support tickets. - Provide context: What are you trying to achieve, what is the end-user interaction, what are you seeing? (full error message, command output, etc.) - Use search.convex.dev to search Docs, Stack, and Discord all at once. - Additionally, you can post your questions in the Convex Community's <#1228095053885476985> channel to receive a response from AI. - Avoid tagging staff unless specifically instructed. Thank you!
sleepless
sleepless6d ago
There is schema.tables.whatever.validator.fields You could do something like
args: { foo: schema.tables.bar.validator.fields.foo },
args: { foo: schema.tables.bar.validator.fields.foo },
or if you want to take any of them (eg for upsert)
args: partial(schema.tables.bar.validator.fields),
args: partial(schema.tables.bar.validator.fields),
Here's a real example if it helps
// Action to update current user's profile data
export const updateCurrentUser = mutation({
args: omit(partial(schema.tables.users.validator.fields), protectedUserFields),
handler: async (ctx, updates) => {
const user = await requireCurrentUser(ctx);
await ctx.db.patch(user._id, {
...updates,
});
},
});
// Action to update current user's profile data
export const updateCurrentUser = mutation({
args: omit(partial(schema.tables.users.validator.fields), protectedUserFields),
handler: async (ctx, updates) => {
const user = await requireCurrentUser(ctx);
await ctx.db.patch(user._id, {
...updates,
});
},
});
Oscar
OscarOP3d ago
I'm trying this but I think I'm mistaken is your schema the defineSchema from schema.ts ?
Oscar
OscarOP3d ago
No description
Oscar
OscarOP3d ago
but yeah since in Convex "everything is Typescript", I suppose what you are suggesting should work one way or another for my codebase

Did you find this page helpful?