Skip to content

Conversation

@sshader
Copy link
Owner

@sshader sshader commented Jun 10, 2024

This is trying out the soon to be launched output validators as they are. I made the relevant types public in the Convex repo, ran npm pack, tweaked convex-helpers so I could get custom functions working, ran npm pack, and then installed both in this project.

Notes:

  • The type errors are pretty bad. I accidentally did v.id("Game") instead of v.id("Games") and the real error was pretty buried (I'll grab a screenshot).
  • I really want a Doc type, especially with Ents. I ended up copying stuff from my schema, manually adding system fields (I think there's an existing helper for that), and then manually adding in fields for any ent edges. At one point I copy pasted from the saved schema in the dashboard since that included the ent edges for me.
  • It's a bummer that returns: v.object({ a: v.string(), b: v.string() }), handler: () => { return { a: "a", b: "b", c: "c" } } will compile (but fail at runtime). This is also true for arg validators, but it means that there's not really any help from TypeScript when it comes to remembering to add in _id, or adding in a property in a helper and forgetting to propagate that all the way to the return value validator.
  • I kind of wanted a validator for PaginationResult (had to reconstruct the type manually, but with validators)
  • Most of my mutations just have returns: v.null()

@vercel
Copy link

vercel bot commented Jun 10, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
proset-g7r2 ❌ Failed (Inspect) Jun 10, 2024 5:49pm

@sshader
Copy link
Owner Author

sshader commented Jun 12, 2024

Example of one of the errors I got (I had v.id("Game") instead of v.id("Games"))

convex/games.ts:25:28 - error TS2769: No overload matches this call.
  Overload 1 of 3, '(fn: { args: { sessionId: StringValidator<string, false, never>; }; returns: ObjectValidator<{ playerId: IdValidator<"Players", Id<"Players">, false, never>; gameId: IdValidator<...>; }, { ...; }, false, "gameId" | "playerId">; handler: (ctx: Overwrite<...>, args: Omit<...>) => ValidatorTypeToReturnType<...>; }): RegisteredMutation<...>', gave the following error.
    Type '(ctx: Overwrite<import("/Users/sshader/proset/node_modules/convex/dist/cjs-types/server/registration").GenericMutationCtx<{ Players: { document: { _id: import("/Users/sshader/proset/node_modules/convex/dist/cjs-types/values/value").Id<"Players">; _creationTime: number; name: string; color: "red" | ... 5 more ... | "...' is not assignable to type '(ctx: Overwrite<import("/Users/sshader/proset/node_modules/convex/dist/cjs-types/server/registration").GenericMutationCtx<{ Players: { document: { _id: import("/Users/sshader/proset/node_modules/convex/dist/cjs-types/values/value").Id<"Players">; _creationTime: number; name: string; color: "red" | ... 5 more ... | "...'. Two different types with this name exist, but they are unrelated.
      Type 'Promise<{ gameId: Id<"Games">; playerId: Id<"Players">; }>' is not assignable to type 'ValidatorTypeToReturnType<{ gameId: Id<"Game">; playerId: Id<"Players">; }>'.
        Type 'Promise<{ gameId: Id<"Games">; playerId: Id<"Players">; }>' is not assignable to type 'Promise<{ gameId: Id<"Game">; playerId: Id<"Players">; }>'.
          Type '{ gameId: Id<"Games">; playerId: Id<"Players">; }' is not assignable to type '{ gameId: Id<"Game">; playerId: Id<"Players">; }'.
            Types of property 'gameId' are incompatible.
              Type 'Id<"Games">' is not assignable to type 'Id<"Game">'.
                Type 'Id<"Games">' is not assignable to type '{ __tableName: "Game"; }'.
                  Types of property '__tableName' are incompatible.
                    **Type '"Games"' is not assignable to type '"Game"'.**
  Overload 2 of 3, '(fn: { args: { sessionId: StringValidator<string, false, never>; }; handler: (ctx: Overwrite<GenericMutationCtx<{ Players: { document: { _id: Id<"Players">; _creationTime: number; name: string; color: "red" | ... 5 more ... | "grey"; score: number; isSystemPlayer: boolean; GameId: Id<...>; UserId: Id<...>; }; fieldPaths: "_id" | ... 2 more ... | "UserId"; indexes: { ...; }; searchIndexes: {}; vectorIndexes: {}; }; ... 4 more ...; Users: { ...; }; }>, { ...; }>, args: Omit<...>) => Promise<...>; }): RegisteredMutation<...>', gave the following error.
    Argument of type '{ args: { sessionId: StringValidator<string, false, never>; }; returns: ObjectValidator<{ playerId: IdValidator<"Players", Id<"Players">, false, never>; gameId: IdValidator<...>; }, { ...; }, false, "gameId" | "playerId">; handler: (ctx: Overwrite<...>, { sessionId }: Omit<...>) => Promise<...>; }' is not assignable to parameter of type '{ args: { sessionId: StringValidator<string, false, never>; }; handler: (ctx: Overwrite<GenericMutationCtx<{ Players: { document: { _id: Id<"Players">; _creationTime: number; name: string; color: "red" | ... 5 more ... | "grey"; score: number; isSystemPlayer: boolean; GameId: Id<...>; UserId: Id<...>; }; fieldPaths:...'.
      Object literal may only specify known properties, and 'returns' does not exist in type '{ args: { sessionId: StringValidator<string, false, never>; }; handler: (ctx: Overwrite<GenericMutationCtx<{ Players: { document: { _id: Id<"Players">; _creationTime: number; name: string; color: "red" | ... 5 more ... | "grey"; score: number; isSystemPlayer: boolean; GameId: Id<...>; UserId: Id<...>; }; fieldPaths:...'.
  Overload 3 of 3, '(fn: UnvalidatedFunction<Overwrite<GenericMutationCtx<{ Players: { document: { _id: Id<"Players">; _creationTime: number; name: string; color: "red" | "orange" | "yellow" | "green" | "blue" | "purple" | "grey"; score: number; isSystemPlayer: boolean; GameId: Id<...>; UserId: Id<...>; }; fieldPaths: "_id" | ... 2 more ... | "UserId"; indexes: { ...; }; searchIndexes: {}; vectorIndexes: {}; }; ... 4 more ...; Users: { ...; }; }>, { ...; }>, [...], Promise<...>>): RegisteredMutation<...>', gave the following error.
    Argument of type '{ args: { sessionId: StringValidator<string, false, never>; }; returns: ObjectValidator<{ playerId: IdValidator<"Players", Id<"Players">, false, never>; gameId: IdValidator<...>; }, { ...; }, false, "gameId" | "playerId">; handler: (ctx: Overwrite<...>, { sessionId }: Omit<...>) => Promise<...>; }' is not assignable to parameter of type 'UnvalidatedFunction<Overwrite<GenericMutationCtx<{ Players: { document: { _id: Id<"Players">; _creationTime: number; name: string; color: "red" | "orange" | "yellow" | "green" | "blue" | "purple" | "grey"; score: number; isSystemPlayer: boolean; GameId: Id<...>; UserId: Id<...>; }; fieldPaths: "_id" | ... 2 more ......'.
      Object literal may only specify known properties, and 'args' does not exist in type 'UnvalidatedFunction<Overwrite<GenericMutationCtx<{ Players: { document: { _id: Id<"Players">; _creationTime: number; name: string; color: "red" | "orange" | "yellow" | "green" | "blue" | "purple" | "grey"; score: number; isSystemPlayer: boolean; GameId: Id<...>; UserId: Id<...>; }; fieldPaths: "_id" | ... 2 more ......'.

 25 export const getOrCreate = mutationWithEnt({
                               ~~~~~~~~~~~~~~~~~
 26   args: {
    ~~~~~~~~~
...
 36   },
    ~~~~
 37 })
    ~~

  node_modules/convex-helpers/server/customFunctions.ts:486:3
    486   handler: (
          ~~~~~~~
    The expected type comes from property 'handler' which is declared here on type '{ args: { sessionId: StringValidator<string, false, never>; }; returns: ObjectValidator<{ playerId: IdValidator<"Players", Id<"Players">, false, never>; gameId: IdValidator<...>; }, { ...; }, false, "gameId" | "playerId">; handler: (ctx: Overwrite<...>, args: Omit<...>) => ValidatorTypeToReturnType<...>; }'
    ```

@sshader
Copy link
Owner Author

sshader commented Jun 12, 2024

I think this is better (with the simplified overloads)

convex/games.ts:33:3 - error TS2719: Type '(ctx: Overwrite<import("/Users/sshader/proset/node_modules/convex/dist/cjs-types/server/registration").GenericMutationCtx<{ Players: { document: { _id: import("/Users/sshader/proset/node_modules/convex/dist/cjs-types/values/value").Id<"Players">; _creationTime: number; name: string; color: "red" | ... 5 more ... | "...' is not assignable to type '(ctx: Overwrite<import("/Users/sshader/proset/node_modules/convex/dist/cjs-types/server/registration").GenericMutationCtx<{ Players: { document: { _id: import("/Users/sshader/proset/node_modules/convex/dist/cjs-types/values/value").Id<"Players">; _creationTime: number; name: string; color: "red" | ... 5 more ... | "...'. Two different types with this name exist, but they are unrelated.
  Type 'Promise<{ gameId: Id<"Games">; playerId: Id<"Players">; }>' is not assignable to type 'ValidatorTypeToReturnType<{ gameId: Id<"Game">; playerId: Id<"Players">; }>'.
    Type 'Promise<{ gameId: Id<"Games">; playerId: Id<"Players">; }>' is not assignable to type 'Promise<{ gameId: Id<"Game">; playerId: Id<"Players">; }>'.
      Type '{ gameId: Id<"Games">; playerId: Id<"Players">; }' is not assignable to type '{ gameId: Id<"Game">; playerId: Id<"Players">; }'.
        Types of property 'gameId' are incompatible.
          Type 'Id<"Games">' is not assignable to type 'Id<"Game">'.
            Type 'Id<"Games">' is not assignable to type '{ __tableName: "Game"; }'.
              Types of property '__tableName' are incompatible.
                Type '"Games"' is not assignable to type '"Game"'.

33   handler: async (ctx, { sessionId }) => {
     ~~~~~~~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants