Git Product home page Git Product logo

Comments (5)

tlancina avatar tlancina commented on May 27, 2024

I see from colinhacks/zod#2474 that ZodEffects is an expected change, but the loss of type information I believe is the bug, since ideally instead of having to redefine the interface we would be able to use type Input = z.infer<typeof SignupCreateSchema>.

from zenstack.

ymc9 avatar ymc9 commented on May 27, 2024

Hi @tlancina , thanks for bringing this up. I believe it's a limitation of zod that after .refine() call, the schema is not a ZodObject anymore. Zod's author confirmed this: colinhacks/zod#2646.

Do you want to manipulate the generated object schema further and then use it for validation? Could you share the ideal way how you want to do it? Maybe we can come up with a workaround here.

from zenstack.

tlancina avatar tlancina commented on May 27, 2024

Hey thanks for the quick response. And apologies, the issue is a little unclear.

Here you have to redefine the type for react-hook-form: https://github.com/ymc9/zenstack-form-validation/blob/5ceea4423e13541e4ddeb49d157d7f6a41432a96/src/app/page.tsx#L33-L38.

What I'd like to do is replace those lines with type Input = z.infer<typeof SignupCreateSchema>. This way, if the schema changes, I don't have to manually update that type.

The issue is not the ZodEffects, it's that all type information gets lost during the zod plugin generation. If we copy and paste the generated schema, we can see that even with refine() and ZodEffects, the underlying types are still there:

const baseSchema = z.object({
    name: z.string(),
    email: z.string().email().endsWith("@zenstack.dev", { message: "Must be a @zenstack.dev email" }),
    adult: z.boolean(),
    beverage: z.string(),
});

function refine(schema: typeof baseSchema) {
    return schema.refine((value) => { var _a, _b; return ((_b = (_a = ['SODA', 'COFFEE', 'BEER', 'COCKTAIL']) === null || _a === void 0 ? void 0 : _a.includes(value === null || value === void 0 ? void 0 : value.beverage)) !== null && _b !== void 0 ? _b : false); }, { message: "Please choose a valid beverage" })
        .refine((value) => { var _a, _b; return ((value === null || value === void 0 ? void 0 : value.adult) || ((_b = (_a = ['SODA', 'COFFEE']) === null || _a === void 0 ? void 0 : _a.includes(value === null || value === void 0 ? void 0 : value.beverage)) !== null && _b !== void 0 ? _b : false)); }, { message: "You must be an adult to drink alcohol" });
}

const refinedSchema = refine(baseSchema)

type Input = z.infer<typeof refinedSchema>
image

Which works just fine:
image

Compare this to the generated schema type once we use @@validate:
image

The underlying types are gone (everything is just any), so it doesn't work anymore:
image

from zenstack.

ymc9 avatar ymc9 commented on May 27, 2024

Thanks a lot for the detailed explanation and for making the PR @tlancina ! It makes very good sense, and the code changes look great! I'll merge it when CI passes and include it in the next release.

I'll probably make a further change after merging your PR to export the schemas before the refine() call and export the refine() function as well, so in case people need to manipulate the object schema further, they can do that and call refine by themselves. Probably a bit more flexible than it is today.

from zenstack.

tlancina avatar tlancina commented on May 27, 2024

Sounds good, thanks!

from zenstack.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.