Formik: incorrect ts definition for connect() function ?

Created on 24 Aug 2018  路  9Comments  路  Source: formium/formik

Current Behavior

In my sample project I have the following error with TS and connect() function when I declare the formik prop type:
(45,15): Type '{}' is not assignable to type 'Readonly'.
Property 'formik' is missing in type '{}'.

https://github.com/rodriguezc/formik-ts/blob/master/src/BasicPart.tsx

Steps to Reproduce

Checkout and run:
https://github.com/rodriguezc/formik-ts.git

The workaround is to add formik attribute on the parent component:
https://github.com/rodriguezc/formik-ts/commit/b4fd4d8956dfca8abb6719532a12200d0cd421ff

Expected behavior

No TS errors.


  • Formik Version: 1.1.1
  • React Version: 16.4.2
  • TypeScript Version: 3.0.1
  • Browser and Version: N/A
  • OS: N/A
  • Node Version: N/A
  • Package Manager and Version: N/A

Most helpful comment

Got it, thank you!
Exporting a connected component without outer props:

interface FormikPartProps {
    formik: FormikContext<MyDto>;
}
class BasicPart extends React.Component<FormikPartProps & {}> {
  ...  
} 
export default connect<{}, MyDto> (BasicPart);

Exporting a connected component with one outer props:

interface FormikPartProps {
    formik: FormikContext<MyDto>;
}

interface OuterProps {
    myOuterProp: string;
}

class BasicPart extends React.Component<FormikPartProps & OuterProps> {
    public render() {
       ...
    }
}

export default connect<OuterProps, MyDto> (BasicPart);

All 9 comments

Connect requires 2 generics. Props and Values.

Got it, thank you!
Exporting a connected component without outer props:

interface FormikPartProps {
    formik: FormikContext<MyDto>;
}
class BasicPart extends React.Component<FormikPartProps & {}> {
  ...  
} 
export default connect<{}, MyDto> (BasicPart);

Exporting a connected component with one outer props:

interface FormikPartProps {
    formik: FormikContext<MyDto>;
}

interface OuterProps {
    myOuterProp: string;
}

class BasicPart extends React.Component<FormikPartProps & OuterProps> {
    public render() {
       ...
    }
}

export default connect<OuterProps, MyDto> (BasicPart);

I am still getting the error even after modifying the component as per mentioned by @rodriguezc

Would be good if this examples in repo also has a TypeScript using connect()

Better if every js example has also similar ts example

Got it, thank you!
Exporting a connected component without outer props:

interface FormikPartProps {
    formik: FormikContext<MyDto>;
}
class BasicPart extends React.Component<FormikPartProps & {}> {
  ...  
} 
export default connect<{}, MyDto> (BasicPart);

Exporting a connected component with one outer props:

interface FormikPartProps {
    formik: FormikContext<MyDto>;
}

interface OuterProps {
    myOuterProp: string;
}

class BasicPart extends React.Component<FormikPartProps & OuterProps> {
    public render() {
       ...
    }
}

export default connect<OuterProps, MyDto> (BasicPart);

In the case of a connected utility component to be used in different forms throughout a project, how would one pass the Values interface (here fixed to MyDto)?

@HyperMaxime I think the best option for this would be a higher order component. You can also make MyDto generic so that you can use this for any form props you want.

const withMyFormWrapper = <TFormValues, TExtraProps = {}>(
    WrappedComponent: React.ComponentType<TFormValues & TExtraProps>
) => connect<TExtraProps, TFormValues>(WrappedComponent);

Edit: wow this is super old didn't mean to ping from the dead!

@johnrom thanks! I got it working with a slightly tweaked version:

const withMyFormWrapper = <TFormValues, TExtraProps = {}>(
    WrappedComponent: React.ComponentType<TExtraProps & {
      formik: FormikContext<TFormValues>;
    }>
) => connect<TExtraProps, TFormValues>(WrappedComponent);

You're absolutely right! Duh me

This is still the sort of thing the HOC types can easily erase. Like how react-redux's connect strips out what you pass for mapState and mapDispatch, or how material-ui's useTheme doesn't make you split your props into two interfaces, it's been possible to do the right thing for a while now.

See here: https://codesandbox.io/s/be-better-formik-9slem?file=/src/App.tsx. ComponentUsingHoc complains that formik isn't being passed to it, while ComponentUsingBetterHoc doesn't. Implementation is the same in both components.

Was this page helpful?
0 / 5 - 0 ratings