-
Notifications
You must be signed in to change notification settings - Fork 458
Description
Context
I use the TS compiler option exactOptionalPropertyTypes: true in my codebase (for general TS logic as well as Convex logic) to prevent a lot of footguns with missing attributes vs attributes with a value of undefined, but it's incompatible with the dynamic types that Convex emits for schema with optional fields:
Repro
const schema = defineSchema({
users: defineTable({
stripeSubStatus: v.optional(v.string()),
}),
});
Convex emits stripeSubStatus?: string | undefined, but at runtime a Convex ctx.db.query would never return undefined for a field, it would just omit it (conflicting with exactOptionalPropertyTypes).
Convex patch operation type safety
With the exactOptionalPropertyTypes flag on, TS properly prevents { foo: undefined } unless I explicitly type it that way, which e.g. reduces accidental field drops for ctx.db.patch operations.
My proposal
As a customer I can't force others to use exactOptionalPropertyTypes, and other customers probably already rely on the current prop?: T | undefined.
To maintain backward compatibility, Convex could add an opt-in type parameter on defineSchema (similar to the existing StrictTableNameTypes extends boolean = true), maybe StrictOptionalTypes extends boolean = false, which would mean Convex emits the stricter prop?: T instead.
Cc @thomasballinger since @ianmacartney mentioned Tom has been internally advocating for this for years.