type Row = Record<string, string>
type Column = {
id: keyof Row;
title: string;
}
type Props<C extends Column, R extends Row> = {
columns: C[];
rows: R[];
onSelect: (row: R) => void;
}
export const Table = <C extends Column, R extends Row>(props: Props<C, R>) => {
...
};
type User = {
id: string;
firstName: string;
lastName: string;
}
type UserColumn = {
id: keyof User;
title: string;
}
declare const userColumns: UserColumn[];
declare const users: User[];
<Table<UserColumn, User>
columns={userColumns}
rows={users}
onSelect={(user/* infered User type */) => {}}
/>
or
<Table
columns={userColumns}
rows={users}
onSelect={(user/* infered User type */) => {}}
/>