Magnus Bull
Magnus Bull

Reputation: 1146

Infer generic type between 2 props in React TypeScript

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

Answers (1)

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

Related Questions