Giter Club home page Giter Club logo

Comments (12)

fabian-hiller avatar fabian-hiller commented on May 9, 2024 2

Yes, I will improve the docs here. Thank you for your feedback!

from valibot.

fabian-hiller avatar fabian-hiller commented on May 9, 2024 1

I have checked this and for me only the properties description and isActive are optional. Can you send me your whole schema code?

from valibot.

fabian-hiller avatar fabian-hiller commented on May 9, 2024 1

Thank you for your feedback. As far as I know, Zod does not allow to merge a transformed object and this can be technically justified. With transform, the object can be transformed to any other data type. For example a JSON string. If Valibot or Zod have no guarantee about the outgoing data, they must either discard the transformation like Valibot or prevent merging completely like Zod.

Furthermore, when merging, Valibot allows overwriting data types if the same key occurs in multiple objects. This is another reason why transform cannot be executed in this case, since otherwise incorrect data in transform or the pipeline is expected.

To make it short. If merge or another object method is applied, transform, as well as the pipeline must be added to the merged schema all over again. I will try to document this better in the long run.

from valibot.

fabian-hiller avatar fabian-hiller commented on May 9, 2024 1

Simply apply the transformation to the merged object scheme.

const createMenuSchema = transform(
  merge([
    object({
      description: optional(string()),
      endIcon: optional(string()),
      isActive: optional(useDefault(boolean(), true)),
      link: string(),
      linkType: nativeEnum(MenuLinkType),
      location: nativeEnum(MenuLocation),
      order: number(),
      parentId: optional(string()),
      startIcon: optional(string()),
      title: string(),
      type: nativeEnum(MenuType),
    }),
    baseSchema,
  ]),
  (menu) => ({ ...menu, slug: slugify(menu.title) })
);

from valibot.

fabian-hiller avatar fabian-hiller commented on May 9, 2024 1

For me your code works without problems and the types are displayed correctly. Does strict in the tsconfig.json have the value true?

from valibot.

fabian-hiller avatar fabian-hiller commented on May 9, 2024 1

Added the info to the docs. Thanks!

from valibot.

harrytran998 avatar harrytran998 commented on May 9, 2024

Sure, I combine two models together

export const baseSchema = object({
  createdDate: optional(string()),
  updatedDate: optional(string()),
});
export enum MenuLinkType {
  INTERNAL = "INTERNAL",
  EXTERNAL = "EXTERNAL",
}
export enum MenuType {
  NORMAL = "NORMAL",
  PROMO = "PROMO",
  NEWS = "NEWS",
}
export enum MenuLocation {
  HEADER = "HEADER",
  FOOTER = "FOOTER",
  SIDEBAR = "SIDEBAR",
}

export const createMenuSchema = merge([
  transform(
    object({
      description: optional(string()),
      endIcon: optional(string()),
      isActive: optional(useDefault(boolean(), true)),
      link: string(),
      linkType: nativeEnum(MenuLinkType),
      location: nativeEnum(MenuLocation),
      order: number(),
      parentId: optional(string()),
      startIcon: optional(string()),
      title: string(),
      type: nativeEnum(MenuType),
    }),
    (menu) => ({ ...menu, slug: slugify(menu.title) }),
  ),
  baseSchema,
]);

export type MenuModel = Output<typeof createMenuSchema>;
  1. All properties will mark as optional
  2. The new model after transform does not contain the slug field 🤔

Hope you can check this.

from valibot.

fabian-hiller avatar fabian-hiller commented on May 9, 2024

Thank you for the details. This is an expected behavior. Please read through issue #26 and let me know what you think.

The important info is in these comments:

from valibot.

harrytran998 avatar harrytran998 commented on May 9, 2024

Thank you for your quick response, I am not good in technical but can contribute to you the user experience from my point of view.

  1. I don't know how to execute the pipe of function in order with valibot. Might be when you execute inside to outside, the result may be correct like the expected result: Remain the object type --> transform with slug --> merge with another schema.
  2. I might think this stuff is really hard technically, but merge and transform it into basic things which anyone using zod did. I guess Zod has a trade-off to do the complicated kinds of stuff like this about bundle size or performances.
  3. If you think this was expected behavior, I think you should talk with more people using this and Zod on their production, might you can find the solutions 😆.

from valibot.

harrytran998 avatar harrytran998 commented on May 9, 2024

Hmm, can you suggest to me how to solve this problem with Valibot?

Bcs after using Valibot, I use this with Zod --> It worked as I expected. The code below for you can try 😆.

export const createMenuSchema = z
  .object({
    description: z.string().optional(),
    endIcon: z.string().optional(),
    isActive: z.boolean().optional().default(true),
    link: z.string(),
    linkType: z.nativeEnum(MenuLinkType),
    location: z.nativeEnum(MenuLocation),
    order: z.number(),
    parentId: z.string().optional(),
    startIcon: z.string().optional(),
    title: z.string(),
    type: z.nativeEnum(MenuType),
  })
  .transform((menu) => ({ ...menu, slug: slugify(menu.title) }))
  .and(baseSchema);

export type MenuModel = z.infer<typeof createMenuSchema>;

from valibot.

harrytran998 avatar harrytran998 commented on May 9, 2024
export const createMenuSchema = transform(
  merge([
    object({
      link: string(),
      title: string(),
      order: number(),
      linkType: nativeEnum(MenuLinkType),
      location: nativeEnum(MenuLocation),
      type: nativeEnum(MenuType),
      description: optional(string()),
      endIcon: optional(string()),
      isActive: optional(useDefault(boolean(), true)),
      parentId: optional(string()),
      startIcon: optional(string()),
    }),
    baseSchema,
  ]),
  (menu) => ({ ...menu, slug: slugify(menu.title) }),
);

export type MenuModel = Output<typeof createMenuSchema>;

image

export const tenantSchema = object({
  id: number(),
  name: string([minLength(1)]),
  description: string(),
});

export type TenantModel = Output<typeof tenantSchema>;

image

Hmm, really weird! Now anything turns to optional(valibot v 0.8.0)

from valibot.

harrytran998 avatar harrytran998 commented on May 9, 2024

Ohhh - It worked! Thank you for your quick response! This should be in the document 😆.

from valibot.

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.