Reputation: 1146
I believe this is possible but I'm not too good with advanced typing in TS (yet) so:
I want to have a React component accept an array of any object shape in one prop, and then emit that same type in a different (event function) prop.
interface Props {
data: AnyGenericRow[];
onRow: (row: AnyGenericRow) => void;
}
How should I type AnyGenericRow
to achieve what I want? I suppose I need to infer the type from data
in some way and then apply that inferred type to the onRow
signature.
Example usage:
const rows: Array<{ foo: 'bar' }> = [];
/* ... */
<Component data={rows} onRow={row => {
/* can `row` be detected as a type of { foo: 'bar' } ? */ }
} />
Perhaps this is super simple but I find it a bit tricky to know exactly what terms to search for to find this.
Bonus question: Can the inferred generic row extend an interface in the component? Perhaps all it takes is to &
it...?
Upvotes: 9
Views: 8168
Reputation: 33051
Here you have:
import React from 'react'
interface Props<T> {
data: T[];
onRow: (row: T) => void;
}
const rows: Array<{ foo: 'bar' }> = [];
function Component<T>(props: Props<T>) {
return null
}
<Component data={rows} onRow={row => {
/* `row` can be detected as a type of { foo: 'bar' } ? */
}} />
Please keep in mind that you can also set generic parameter of Component
explicitly:
<Component<{ foo: 'bar' }> data={[]} onRow={row => {
/* `row` can be detected as a type of { foo: 'bar' } ? */
}} />
Upvotes: 17