Skip to content

[TypeScript] SharedRenderProps.component has incorrect type React.ComponentType<T | void> instead of React.ComponentType<T> #4061

@Michaelkh20

Description

@Michaelkh20

Description:

The component prop in SharedRenderProps interface has an incorrect TypeScript type that includes void in the union.

Current type in types.d.ts:199:

export interface SharedRenderProps<T> {
    component?: keyof React.JSX.IntrinsicElements | React.ComponentType<T | void>;
    render?: (props: T) => React.ReactNode;
    children?: (props: T) => React.ReactNode;
}

Expected type:

export interface SharedRenderProps<T> {
    component?: keyof React.JSX.IntrinsicElements | React.ComponentType<T>;
    render?: (props: T) => React.ReactNode;
    children?: (props: T) => React.ReactNode;
}

Why this is a bug:

Looking at the runtime implementation in formik.esm.js (FieldArray render method, line ~1818):

var props = _extends({}, arrayHelpers, {
  form: restOfFormik,
  name: name
});

return component ? createElement(component, props) : render ? render(props) : children ? ...

The component receives exactly the same props as render. For FieldArray, this is FieldArrayRenderProps. The component will always receive these props - there's no code path where it receives void.

Impact:

When using the component prop with a properly typed component, TypeScript produces false errors because it expects the component to accept void as props:

interface MyComponentProps {
  form: FormikProps<any>;
  name: string;
  push: (obj: any) => void;
  // ... other FieldArrayRenderProps
}

const MyComponent: React.FC<MyComponentProps> = (props) => { ... };

// TypeScript error: Type 'FC<MyComponentProps>' is not assignable to type 'ComponentType<FieldArrayRenderProps | void>'
<FieldArray name="items" component={MyComponent} />

Workaround:

Use children or render props instead of component for better type safety:

<FieldArray name="items">
  {(props) => <MyComponent {...props} />}
</FieldArray>

Suggested fix:

Remove void from the union type in SharedRenderProps:

export interface SharedRenderProps<T> {
-    component?: keyof React.JSX.IntrinsicElements | React.ComponentType<T | void>;
+    component?: keyof React.JSX.IntrinsicElements | React.ComponentType<T>;
    render?: (props: T) => React.ReactNode;
    children?: (props: T) => React.ReactNode;
}

Environment:

  • Formik version: 2.4.9
  • TypeScript version: 4.x+

Labels: bug, typescript, types

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions