fastify-type-provider-typebox icon indicating copy to clipboard operation
fastify-type-provider-typebox copied to clipboard

Reply type check improvement

Open StepanMynarik opened this issue 9 months ago • 3 comments

Prerequisites

  • [X] I have written a descriptive issue title
  • [X] I have searched existing issues to ensure the feature has not already been requested

🚀 Feature Proposal

Hi,

Look at the followng code:

fastify.post(
    "/users/:id",
    {
      schema: {
        body: Type.Object({
          firstName: Type.String({ minLength: 1, maxLength: 9 }),
          lastName: Type.String({ minLength: 1, maxLength: 9 }),
        }),
        response: {
          201: userSchema,
        },
      },
    },
    async (_request, response) => {
      return response.code(201).send({ id: 1, fullName: "" });
    }
  );

Type checking works nice, everything is correct, everyone is happy.

Now imagine changing '.code(' function argument from schema defined 201 to 300 for example. TypeScript will still be happy. Even though we return something not mentioned in the schema. It would be nice if this could be reported as well?

Even worse though, imagine specifying one more code in the response section of the schema. 300 for example, with a different response type. Now try sending mismatched reply from the handler. Like code 201 with the payload that, according to the schema, belongs to code 300. Typescript will again be happy. Now if this could be solved, then that would be even better.

I would love it if the 'send' function could accept code parameter directly so that the type inference could be more rigid and correct in all cases. Or some other typescript trickery that could still allow for function chaining with more solid type inference.

Perhaps I'm missing something here?

Summary:

  • I would like code/send type mismatch prevention (based on schema)
  • I would also like schema undefined status code prevention

Motivation

Better type inference that could lead to absolutely type safe reply composition.

Example

fastify.post(
    "/users/:id",
    {
      schema: {
        body: Type.Object({
          firstName: Type.String({ minLength: 1, maxLength: 9 }),
          lastName: Type.String({ minLength: 1, maxLength: 9 }),
        }),
        response: {
          201: userSchema,
          300: someOtherSchema,
        },
      },
    },
    async (_request, response) => {
      return response.code(201).send({ id: 1, fullName: "" });
    }
  );

StepanMynarik avatar Nov 10 '23 21:11 StepanMynarik

Perhaps a question most suitable for @sinclairzx81 ?

StepanMynarik avatar Nov 13 '23 20:11 StepanMynarik

Also @fastify/typescript could you pitch in?

I would love it if the 'send' function could accept code parameter directly so that the type inference could be more rigid and correct in all cases.

I think we could add this to Fastify proper.

mcollina avatar Nov 15 '23 16:11 mcollina

This would be amazing. I need to take a deeper look into it, though.

fox1t avatar Nov 16 '23 08:11 fox1t