Unform: Use custom type instead object for submit handler

Created on 17 May 2019  路  5Comments  路  Source: unform/unform

What would you like to be added:

unform/lib/Form.tsx

make this changes

+ interface FormContent {
+    [key: string]: string;
+ }

interface Props {
  initialData?: object;
  children: React.ReactNode;
  context?: Context;
  schema?: ObjectSchema<object>;
-  onSubmit: (data: object, helpers: Helpers) => void;
+ onSubmit: (data: FormContent, helpers: Helpers) => void;
}

Is your enhancement request related to a problem? Please describe.

Typescript shows an error when we can try to access data parameter values with array syntax like this: data[key]. This occurs because data is typed with object type, and each value of object type has implicitly any type.

One way to solve this problem is to use a custom type, like above.

Additional context

|unform-error|
|:----------------------------------------------:|
| with object type |
| data[key] has implicit any type |

|unform-success|
|:----------------------------------------------:|
| with FormContent type |
| data[key] has string type |

feature request

Most helpful comment

@diego3g Of course! I'll submit it tonight.

All 5 comments

@cleitonper Great! Can you submit a PR with this implementation?

@diego3g Of course! I'll submit it tonight.

Why not make it generic? What if it is a complex structure with arrays and stuff? I would do:

interface Props<T> {
  initialData?: object;
  children: React.ReactNode;
  context?: Context;
  schema?: ObjectSchema<object>;
  onSubmit: (data: T, helpers: Helpers) => void;
}

Also making Context a generic. What do you think?

@zaguiini nice! make use of the Generics is the correct solution for the data parameter, but instead of use a generic type in the Props we can use it in a separate function type. something like this:

interface FormContent {
  [key: string]: string;
}

interface SubmitHandler<T = FormContent> {
  (data: T, helpers: Helpers): void
}

and we can create our submit handler like this:

const submitHandler: SubmitHandler = (data, helpers) => {
 // default data type is FormContent because basic forms
 // return only key(string)/value(string) pairs.
}

/**
 * with a custom nested type
 */

interface Item {
  craftDate: Date;
  name: string;
  description: string;
  price: number;
}

interface Character {
  nickname: string;
  lastLogin: Date;
  hp: number;
  sp: number;
  items: Item[];
}

const submitHandler: SubmitHandler<Character> = (data, helpers) => {
  // my submit code
}

thanks for your tip. more suggestions are welcome.

PR #44 is ready to merge in order to solve this issue.

Was this page helpful?
0 / 5 - 0 ratings