teslamotors/informed

Missmatched Types and Methods

motleydev opened this issue · 13 comments

Describe the bug
I've been using Informed for a little over a week so this issue spans previous to the 4.2 release and is persistent after the 4.2 release. I've deleted my modules folder, and the problem persists.

Following the getting started guide, when I install Informed and attempt to import the different components, the majority complain about having no exported member matching the name.

CleanShot 2022-02-12 at 12 38 15

Using the formApi hook, and attempting to call setValue checks out from the types, but the method doesn't exist when actually attempted to be invoked.

It seems like there is some kind of large type mismatch/cache issue but I, unfortunately, don't know where else to look at this point.

To Reproduce

Scaffold a boilerplate NextJs project with typescript.
Following the getting started guide from Informed.
Try to use a formApi setValue method (or the documented setValues that typescript complains doesn't exist).

My files use the .tsx extension if that makes a difference?

Can you try to recreate in a sandbox or something. I think you are the only person who has this issue.

Sure! Following the instructions, I listed above. This is a brand new setup (Feb 15, 12pm CET)

TLDR; Repo: https://github.com/motleydev/sandbox-informed

  1. Scaffold the app: yarn create next-app --typescript
  2. Enter the directory, add informed yarn add informed
  3. Open an index page from NextJs, paste in the imports: import { Form, Input, Select, Checkbox, Relevant, Debug } from 'informed';

From there it already shows that the exports are missing (along with unused) - add the boilerplate code:

`<Form onSubmit={onSubmit}>
    <Input name="name" label="Name" placeholder="Elon" />
    <Input name="age" type="number" label="Age" required="Age Required" />
    <Input name="phone" label="Phone" formatter="+1 (###)-###-####" />
    <Select name="car" label="Car" initialValue="ms">
      <option value="ms">Model S</option>
      <option value="m3">Model 3</option>
      <option value="mx">Model X</option>
      <option value="my">Model Y</option>
    </Select>
    <Checkbox name="married" label="Married?" />
    <Relevant when={({ formState }) => formState.values.married}>
      <Input name="spouse" label="Spouse" />
    </Relevant>
    <button type="submit">Submit</button>
    <Debug />
  </Form>

And now it only complains about the missing exports.

CleanShot 2022-02-15 at 11 57 20@2x

Incorrect type

Additionally, import the useFormApi hook and call it on the page:

const formAPI = useFormApi()

Add it to a button below the form.

<button
          onClick={() => {
            formAPI.setValue("email", "foo@bar.baz");
          }}
        >
          Set Email to foo@bar.baz
        </button>

The types seem to be present, but calling the actual method yields an error.

CleanShot 2022-02-15 at 12 05 17@2x

@joepuzzo Looks like we're still missing types for the form field components (in 4.5.1)

@motleydev the error for formApi.setValue occurs because you are calling useFormApi from outside the form context, it's not a type error, it is a run time js error. informed uses React context as the means to share data across components.

To achieve what you're trying to you can create a component that gets rendered as a child of Form:

const SetValueButton = () => {
  const formAPI = useFormApi();
  return (
    <button
      type="button"
      onClick={() => {
        formAPI.setValue("email", "foo@bar.baz");
      }}
    >
      Set Email to foo@bar.baz
    </button>
  )
}

// render SetValueButton as a child of <Form>
<Form>
   ...
   <SetValueButton />
</Form>

Following works:
image


A side note: it looks like you were passing incorrect props for required, required is a boolean. It looks like docs are missing some of the props.

image

@ghoshabhi Ah thanks! I guess that makes sense in context with a Form, its just not something I was familiar with. Is this explicit in the docs? That might help. If you "stop to think about it" then it makes sense, because, forms. But its a bit a-typical for a lot React lib APIs that don't have something like a "FormProvider" component.

Re the required props, that's literally copy and paste from the website, so maybe another place to update. :) I'll try to poke around and see where that needs to get updated.

CleanShot 2022-02-19 at 08 05 05@2x

required can be a string and used as the error value. So if the types have it as bool it is wrong.

Is there a PR I can track on where the types issue might be resolved? Or is this a "PRs welcome" problem. :) I'm still quite beginner with my ts skills.

Working on it now

@motleydev This should all be fixed now in latest version.

Actually I may have forgot to do Debug 🤦‍♂️

@ghoshabhi it seems the latest update might have introduced a type regression on useFormApi, this is the list of available methods of useFormApi - if I recall your proposed solution as working in the previous version.

(Length 26)
getValue
setValue
getMaskedValue
setMaskedValue
getTouched
setTouched
getError
setError
getFocused
setFocused
getData
resetField
reset
getFormState
getPristine
getDirty
validateField
getFieldState
getInitialValue
touchAllFields
validate
asyncValidate
setValues
setTheseValues
submitForm
clearValue

These are the typed methods:

(Length 19)
getValue
setValue
getMaskedValue
setMaskedValue
getTouched
setTouched
getError
setError
getFocused
setFocused
resetField
reset
getFormState
getPristine
getDirty
getFieldState
validate
validateField
submitForm

Yup looks like I missed a few types I will add and keep this open until I do add

Hey, just checking on the current status of this? Have these been updated?

Types have been updated many times since then please try with the latest version.