Home > OS >  what is the type of functional component with generic type using compound components
what is the type of functional component with generic type using compound components

Time:11-06

I have a compound component with three children and I need to declare the type of each child. all children are working fine except one with generic type always returns an error that expects 0 arguments and got 1. enter image description here

this is the type I want to change enter image description here

this is the error message that appears when I use the component

this is the component itself

import React from 'react'
import Select from 'react-select'
import { SelectInputI } from '../models'

    export function SelectInput<T>({
      value: inputValue,
      onChange: onInputChange,
      onBlur,
      getSelectValue,
      error,
      name,
      handleOptionLabel,
      handleOptionValue,
      options,
      placeholder,
    }: SelectInputI<T>) {
      return (
        <>
          <Select<T>
            name={name}
            defaultValue={inputValue}
            value={inputValue}
            isSearchable
            placeholder={placeholder}
            onChange={(e: any) => {
              onInputChange(name, () => getSelectValue())(e)
            }}
            getOptionLabel={handleOptionLabel}
            getOptionValue={handleOptionValue}
            options={options}
            onBlur={onBlur}
          />
          {error && <p>{error}</p>}
        </>
      )
    }

enter image description here

CodePudding user response:

One you resolve React.FC<SelectInputI<any>> then it is not a generic type.

Also, React.FC can't be made to be generic at call time, which is one of many reasons you should not be using it.

You are basically doing this:

type Generic<T> = { value: T }
type A = Generic<any>
type B = A<{ test: boolean }> // Type 'A' is not generic.(2315)

What you need to do is this:

type Generic<T> = { value: T }
type A<T> = Generic<T> // type A is now generic
type B = A<{ test: boolean }> // fine

You omitted the SelectInputI type, so lets assume its this:

type SelectInputI<T> = {
    value: T
    onChange: (newValue: T) => void
}

And if you want a generic component that uses that type as props, and accepts a generic value type there, then it's type would be:

<T>(props: SelectInputI<T>) => JSX.Element

So if I stubbed out an object with that type:

declare const NewSearch: {
    SelectInput: <T>(props: SelectInputI<T>) => JSX.Element
}

Then it works as you expect it to.

const result = <NewSearch.SelectInput<{ label: string, value: string }>
    value={{ label: 'a', value: 'b' }}
    onChange={(newValue) => console.log(newValue)}
/>

See playground

  • Related