selem1324
selem1324

Reputation: 23

Typescript React, How to provide type infomation for a component which recives a custom input component as props?

How do i provide the type of props for the CustomComponent which the component Foo recieves as props, the CustomComponent can be for example the CustomInput component. I can use the generic React.FC<T> but how to the type for T because it need to have types for all the attirbutes for the input element(passing InputProps doesn't work) and also the custom component can also be a class component that can receive the same props, So how do i create the interface FooProps where it can receive the custom component as both a functional or class component and the custom component takes the props of all the attributes of a input element plus the prop styleVariant.

interface FooProps {
   customComponent: React.FC<???> // doesn't work
   // other props // works
}

const Foo: React.FC<FooProps> = ({ children, customComponent: CustomComponent }) => {
    
   return (
       <div>
           {children}
           <CustomComponent type="text" styleVariant="primary"/> // compiler complains
       </div>

   )

}


interface InputProps {
  styleVariant: string;
}

const CustomInput: React.FC<InputProps> = ({ styleVariant, ...rest }) => {
   // something to do with styleVariant

   return <input {...rest}/>
}

This is the error that i get, I hope the question is understandable. Thanks in advance.

Type '{ type: string; styleVariant: string; }' is not assignable to type 'IntrinsicAttributes & { styleVariant: string; } & { children?: ReactNode; }'.
  Property 'type' does not exist on type 'IntrinsicAttributes & { styleVariant: string; } & { children?: ReactNode; }'.ts(2322)

Upvotes: 2

Views: 467

Answers (1)

subashMahapatra
subashMahapatra

Reputation: 6847

Looks like you need to use React.HTMLProps.

interface InputProps extends React.HTMLProps<HTMLInputElement> {
   styleVariant: string;
   // type for any other custom props you want to pass
}

Since the custom component can either be a functional component or can also be a class component, you can use React.ComponentType generic which is just union of type FunctionComponent and ComponentClass and also takes a type argument for props.

// you can pass InputProps to the React.ComponentType generic as -
// type argument for props
type TCustomComponent = React.ComponentType<InputProps>

interface FooProps {
  customComponent: TCustomComponent

 // other props for Foo compoent
}


const Foo: React.FC<FooProps> = ({ children, customComponent: CustomComponent }) => {
    
  return (
    <div>
      {children}
      <CustomComponent type="text" styleVariant="primary"/>
    </div>
 );
}

Upvotes: 1

Related Questions