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

setErrors typescript contract is misleading #4396

Closed
1 of 5 tasks
quilin opened this issue Jul 29, 2023 · 1 comment
Closed
1 of 5 tasks

setErrors typescript contract is misleading #4396

quilin opened this issue Jul 29, 2023 · 1 comment
Labels
🐛 bug Unintended behavior 👕 TypeScript TypeScript typings issue

Comments

@quilin
Copy link

quilin commented Jul 29, 2023

What happened?

I use vee-validate 4 with composition API for Vue 3 with TypeScript and tried to create a form that is validated both on client and server side. In my case it's the login form, and the server contract in case of bad request suggests that every field may have multiple error codes.

In my case the BadRequestError looks like this:

export interface BadRequestError extends GeneralError {
  errors: { [field: string]: ValidationErrorCode[] };
}

export enum ValidationErrorCode {
  Some = "Some",
  Fancy = "Fancy",
  Codes = "Codes",
  ForI18N = "ForI18N",
}

And here's my "server side handling". Basically, the idea is that when the API call is done, I want to push the server validation results into form. But the setErrors (in both handleSubmit actions argument and useForm returning value contract) only allows me to pass single string. However, if I pass the array of strings and "mask" it for TS (with as unknown as string) it works like a charm.

const { handleSubmit, meta, errorBag } =
  useForm<LoginCredentials>({
    validationSchema: object({
      login: string().required(ValidationErrorCode.Some),
      password: string().required(ValidationErrorCode.Some),
    }),
  });

const loading = ref(false);
const submit = handleSubmit(async (values, { setErrors }) => {
  const { signIn } = useUserStore();
  loading.value = true;
  const badRequest: BadRequestError | null = await signIn(values);
  loading.value = false;
  if (badRequest) {
    setErrors({
      login: badRequest.errors["login"] as unknown as string,
      password: badRequest.errors["password"].map(e => e.toString()), // error here TS2322: Type string[] is not assignable to type string
    });
  } else {
    emit("login");
  }
});

I'd say it looks like an error in TS definition? Or am I doing something wrong here?

Reproduction steps

  1. Use TypeScript
  2. Create typed form
  3. Try and push errors to the certain field as array of strings
  4. You should have TS error TS2322: Type string[] is not assignable to type string

Version

Vue.js 3.x and vee-validate 4.x

What browsers are you seeing the problem on?

  • Firefox
  • Chrome
  • Safari
  • Microsoft Edge

Relevant log output

No response

Demo link

Sorry, can't

Code of Conduct

@logaretm logaretm added 🐛 bug Unintended behavior 👕 TypeScript TypeScript typings issue labels Jul 29, 2023
@logaretm
Copy link
Owner

logaretm commented Jul 29, 2023

You are correct, I fixed this just now and should up with the next patch. Thanks for reporting this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐛 bug Unintended behavior 👕 TypeScript TypeScript typings issue
Projects
None yet
Development

No branches or pull requests

2 participants