Skip to content

Make schema fields emit prop?: T (not prop?: T | undefined) to align with runtime + exactOptionalPropertyTypes #211

@AtAFork

Description

@AtAFork

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions