cloudflare / chanfana

OpenAPI 3 and 3.1 schema generator and validator for Hono, itty-router and more!
https://chanfana.pages.dev
MIT License
263 stars 35 forks source link

DataOf not really working? #148

Open etodanik opened 2 months ago

etodanik commented 2 months ago

I'm trying to use DataOf on a project, and TypeScript keeps resolving everything to any.

For example, I have:

    requestBody: z.object({
      address: z.string(),
      chainId: z.string(),
      token: z.string(),
    }),

And then I do:

    data: DataOf<typeof CreateSignInDataPost.schema>

But the resolved types are always: image

carafelix commented 2 months ago

This is kind of the default behavior, since it looks like they haven't implement it with full functionality yet, defeating the a lot of purpose in the package, since validation it's crucially needed for POST requests, and using it with type inference. If you specified requestBody it also prevents you from reading/parsing it manually since the body was already used to construct the data object. That procedure it's documented here. But it's a contradiction, since if you define BodyRequest, it's not possbile to request.json() the body, it's already used and inside the data object. In the docs they also use data.any as specified here. The data does indeed goes trough the validation process and all, but it's type it's not inferred into the data object.

Also the RequestBody constructor , besides not being documented, does not pass down it's types to its content object, it's always any, it could accept a type parameter at least. Also it does not comply with being a zodType.

the related type inference code is here: https://github.com/cloudflare/itty-router-openapi/blob/5cd88e4496a07cd3707ca59bc4700646303640b7/src/types.ts#L221-L226

@G4brym

carafelix commented 2 months ago

you can always declare it manually, but that defeats the purpose.

export class ExampleRoute extends OpenAPIRoute {
    static schema: OpenAPIRouteSchema = {
       // more things
        requestBody: MySchema
        }

     // in the handler:
     async handle(
        request: Request,
        data: DataOf<typeof ExampleRoute.schema> & {
            body: z.TypeOf<typeof MySchema>>
        }
    ){/** doer */}
}

 export const MySchema = z.object({
  foo: fooSchema,
  bar: barSchema
 })
G4brym commented 1 month ago

Hello, this part will get reworked on the next major release, i just didn't have enough time yet to get around to it