jquense / yup

Dead simple Object schema validation
MIT License
22.93k stars 934 forks source link

Issue with adding a custom method #2234

Open t0rum89 opened 4 months ago

t0rum89 commented 4 months ago

I'm trying to add a custom method to Yup for my schemas.

declare module 'yup' {
  interface StringSchema {
    password(message?: string): StringSchema;
  }
}

function password(
  this: Yup.StringSchema,
  message: string = 'Password should be between 6 and 40 characters long',
) {
  return this.min(6, message).max(40, message);
}

Yup.addMethod(Yup.string, 'password', password);

And I'm going to use it like this:

export const changePasswordValidationSchema = Yup.object().shape({
  current_password: Yup.string().required('Current password is required').password(),
  password: Yup.string().required('New password is required').password(),
});

But in that case I get a possible undefined for my fields:

const changePasswordValidationSchema: Yup.ObjectSchema<{
    current_password: string | undefined;
    password: string | undefined;
}, Yup.AnyObject, {
    current_password: undefined;
    password: undefined;
}, "">

which causes an error in the resolver:

  const form = useForm<UpdatePasswordPayload>({
    resolver: yupResolver(changePasswordValidationSchema),
    defaultValues: {
      current_password: '',
      password: '',
    },
  });
Type 'Resolver<{ password?: string | undefined; current_password?: string | undefined; }>' is not assignable to type 'Resolver<UpdatePasswordPayload, any>'.
  Types of parameters 'options' and 'options' are incompatible.
    Type 'ResolverOptions<UpdatePasswordPayload>' is not assignable to type 'ResolverOptions<{ password?: string | undefined; current_password?: string | undefined; }>'.
      Type '{ password?: string | undefined; current_password?: string | undefined; }' is not assignable to type 'UpdatePasswordPayload'.ts(2322)
(property) resolver?: Resolver<UpdatePasswordPayload, any> | undefined

My type:

export type UpdatePasswordPayload = {
  current_password: string;
  password: string;
};

I have tried changing the order in the schema to:

export const changePasswordValidationSchema = Yup.object().shape({
  current_password: Yup.string().password().required('Current password is required'),
  password: Yup.string().password().required('New password is required'),
});

But in this case, methods called after mine don't work. Perhaps the context .this lost for them. How i can fix this?