I'm building an input component that takes a displayName
that is a string and a value
that should be a generic. It also takes a function as a prop that needs to fire and handle that generic value when the input is changed.
So, let's say MyInterfaceXYZ
holds the displayName
and value
like so:
interface MyInterfaceXYZ<T> {
displayName: string
value: T
}
We then want this generic value to be used in our main props interface that wraps our first interface... Like the one below (but my syntax is wrong I think):
interface MyComponentProps<T> {
myFunctionThatTakesMyGeneric: (value: T) => void
options: MyInterfaceXYZ<T>[]
}
We then want to pass use this as our props in our react component - where we will receive a generic from an onChange listener.
// The syntax on the line below is totally invalid
const InputSelect: React.FC<MyComponentProps<T>> = ({
myFunctionThatTakesMyGeneric,
options,
}) => {
// `<T extends MyInterfaceXYZ>` requires 1 argument
// that I don't know how to pass here
function onChangeHandler<T extends MyInterfaceXYZ>(option: T) {
myFunctionThatTakesMyGeneric(option.value)
}
return (
<>
<myElement onChange={onChangeHandler}>
Blah blah!
</myElement>
</>
)
How can I modify the syntax so the above code is valid?
CodePudding user response:
You don't actually need to make the onChangeHandler
generic.
import React from 'react'
interface MyInterfaceXYZ<T> {
displayName: string
value: T
}
interface MyComponentProps<T> {
myFunctionThatTakesMyGeneric: (value: T) => void
options: MyInterfaceXYZ<T>[]
}
// The syntax on the line below is totally invalid
function InputSelect<T>({
myFunctionThatTakesMyGeneric,
options,
} : MyComponentProps<T>) {
// `<T extends MyInterfaceXYZ>` requires 1 argument
// that I don't know how to pass here
const onChangeHandler = (option: MyInterfaceXYZ<T>) => {
myFunctionThatTakesMyGeneric(option.value)
}
return (
<>
<div onChange={() => onChangeHandler(options[0])}>
Blah blah!
</div>
</>
)
}
<>
<InputSelect myFunctionThatTakesMyGeneric={(a:string) => {console.log(a);}} options={[{displayName: 'string', value:'1'}]} />
<InputSelect myFunctionThatTakesMyGeneric={(a:number) => {console.log(a);}} options={[{displayName: 'number', value:1}]} />
</>
Also I changed the onChange
to onChange={() => onChangeHandler(options[0])}
, because you need to pass an option to the function. options[0]
is probably not what you want.