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

<Form {context}> produces type error with TypeScript #148

Open
jtlapp opened this issue Nov 10, 2021 · 4 comments
Open

<Form {context}> produces type error with TypeScript #148

jtlapp opened this issue Nov 10, 2021 · 4 comments
Labels
bug Something isn't working

Comments

@jtlapp
Copy link

jtlapp commented Nov 10, 2021

Summary

With TypeScript, I would like to both use the helper components and have the values passed to my onSubmit handler be typed. In order to do this, I have to call createForm (to get type inference) and pass the resulting context to the Form helper. But when I do this I get a type error saying that my FormState type "is not assignable to type 'FormState<Record<string, any>>".

Example

The following working code produces the error:

<script lang="ts">
  import * as yup from 'yup';
  import { createForm, Form, Field, ErrorMessage } from 'svelte-forms-lib';

  const schema = yup.object().shape({
    title: yup.string().required().min(4),
    description: yup.string().required().min(10)
  });

  const context = createForm({
    initialValues: {
      title: '',
      description: ''
    },
    validationSchema: schema,
    onSubmit: (values) => {
      alert(JSON.stringify(values));
    }
  });
</script>

<Form {context}> <!-- TYPE ERROR -->
  <div>
    <label for="title">Title</label>
    <Field type="text" name="title" id="title" />
    <ErrorMessage name="title" />
  </div>
  <div>
    <label for="description">Description</label>
    <Field type="textarea" name="description" />
    <ErrorMessage name="description" />
  </div>
  <button type="submit">Submit</button>
</Form>

Here is the type error:

Type 'FormState<{ title: string; description: string; }>' is not assignable to type 'FormState<Record<string, any>>'.
  Types of property 'updateField' are incompatible.
    Type '(field: "title" | "description", value: any) => void' is not assignable to type '(field: string, value: any) => void'.
      Types of parameters 'field' and 'field' are incompatible.
        Type 'string' is not assignable to type '"title" | "description"'.

Workaround

I am using the following workaround for now, declaring the context to have type 'any':

  const context: any = createForm({ ... });

Possible fixes

I suspect that changing Record<string, any> to {[key: string]: any} in index.d.ts might correct the problem.

@tylkomat
Copy link

tylkomat commented Nov 26, 2021

I think you are mixing two different ways of creating the form.

When you use the Form component you just have to provide the configuration that you now put into createForm. You don't have to use createForm itself.

When you just use a plain HTML <form/> element, then you use createForm.

@jtlapp
Copy link
Author

jtlapp commented Nov 26, 2021

Okay, thanks. I can make the type errors go away by doing that, but it makes too many type errors go away. Notice that I do not get a type error in the following code because the types of the initialValues properties are not inferred:

Screen Shot 2021-11-26 at 09 18 17

Notice that when I use createForm() the types of the initialValues properties are inferred:

Screen Shot 2021-11-26 at 09 19 37

Besides, the type declaration indicates that the form context is supposed to be a valid input to the Form component, and providing the form context as input actually works (aside from the type error):

export type FormProps<Inf = Record<string, unknown>> = {
  context?: FormState;
  initialValues?: Inf;
  onSubmit?: ((values: Inf) => any) | ((values: Inf) => Promise<any>);
  validate?: (values: Inf) => any | undefined;
  validationSchema?: ObjectSchema<any>;
} & svelte.JSX.HTMLAttributes<HTMLFormElement>;

/* ... */

declare class Form extends SvelteComponentTyped<
  FormProps,
  Record<string, unknown>,
  {
    default: FormState;
  }
> {}

@jtlapp
Copy link
Author

jtlapp commented Nov 26, 2021

I forked the repo to experiment with a possible solution, but I get this error that I can't figure out how to resolve:

Cannot find lib definition for 'svelte2tsx'.ts(2726)

Screen Shot 2021-11-26 at 10 06 29

The TypeScript docs indicate that /// <reference lib="some-lib-name" /> is for referencing "built-in" libraries.

@JoshAwaze
Copy link

Any update on this issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants