Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ObjectSchema type vs ObjectSchema class vs object+shape #2200

Open
hikeeba opened this issue Apr 11, 2024 · 2 comments
Open

ObjectSchema type vs ObjectSchema class vs object+shape #2200

hikeeba opened this issue Apr 11, 2024 · 2 comments

Comments

@hikeeba
Copy link

hikeeba commented Apr 11, 2024

What is the difference, and intended use case, for each of these 3 things? The documentation on ObjectSchema is very limited, and only appears to refer to it as a type and not as a class.

For example, what is the different between AccountSchemaA and AccountSchemaB in the code below?

interface Account {
  username: string;
  email: string;
  phone: string;
}

const AccountSchemaA = new yup.ObjectSchema<Account>({
  username: yup.string().required(),
  email: yup.string().required(),
  phone: yup
    .string()
    .required()
    .matches(/^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/, {
      message: 'Phone number must be in the format (XXX) XXX-XXXX',
      excludeEmptyString: true,
    }),
});

const AccountSchemaB: yup.ObjectSchema<Account> = yup.object({
  username: yup.string().required(),
  email: yup.string().required(),
  phone: yup
    .string()
    .required()
    .matches(/^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/, {
      message: 'Phone number must be in the format (XXX) XXX-XXXX',
      excludeEmptyString: true,
    }),
});

From what I can tell, adding an unexpected property to AccountSchemaA, like in the example below, gives an error, but this does not happen for AccountSchemaB.

The error is Object literal may only specify known properties, and 'bob' does not exist in type 'Shape<Account, AnyObject>'.ts(2353).

const AccountSchemaA = new yup.ObjectSchema<Account>({
  username: yup.string().required(),
  email: yup.string().required(),
  bob: yup.string(),
  phone: yup
    .string()
    .required()
    .matches(/^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/, {
      message: 'Phone number must be in the format (XXX) XXX-XXXX',
      excludeEmptyString: true,
    }),
});

Any details on this would be super helpful to make sure we are using this as intended and understand the tradeoffs between the two.

Thanks!

@hikeeba
Copy link
Author

hikeeba commented Apr 11, 2024

It may be that AccountSchemaB would throw an error at compile time with the added bob property, but for AccountSchemaA this error shows up immediately in the editor.

@jquense
Copy link
Owner

jquense commented Apr 18, 2024

there is no difference in behavior, the types are just different on the class vs the factory function. In general the types are going to be less accurate if you use the schema class directly. There are a lot of generics meant to be used in particular ways on them. Prefer the factory functions unless you are comfortable with complex generics

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

No branches or pull requests

2 participants