A
A
Alexey Chernyshov2020-10-18 22:13:49
typescript
Alexey Chernyshov, 2020-10-18 22:13:49

How to set a generic for an array in an object?

Please tell me how to set up the correct generic (I'm not familiar with them).

The bottom line is this:
there is a Table component that accepts props described in the ITable type.
The columns prop takes an array in ITableColumn format where in the formant.item key is the format passed to the Table component in the rows prop.

How to specify correct generics?
online editor

There is an example:

import React from 'react';
import { render } from 'react-dom';

type ITableColumn<D extends object> = {
  property: string;
  format?: (value: any, item: D) => React.ReactNode | string | number;
  header?: any;
  footer?: any;
};

type ITable<T extends object, D extends object> = {
  isLoading?: boolean;
  columns: ITableColumn<D>[];
  rows: Array<T>;
};

type IContext<D extends object> = {
  rows: any;
  columns: ITableColumn<D>[];
};

const getColumns = (): ITableColumn[] => [
  {
    property: 'name',
    format: (value, item) => {
      const { lastName } = item;
      return `${value} ${lastName}`;
    },
    header: 'heade',
    footer: 'footer'
  },
  {
    property: 'count',
    header: 'heade',
    footer: 'footer'
  }
]

interface AppProps { }
interface AppState {
  name: string;
}

const Table:React.FC<ITable> = ({ isLoading, columns, rows }) => {
  return <h1>table</h1>
}

const App = () => (
  <div>
    <Table 
      columns={getColumns()} 
      rows={[
        { name: 'userName 0', lastName: 'userLastName 0', count: 10 },
        { name: 'userName 1', lastName: 'userLastName 1', count: 20 },
        { name: 'userName 2', lastName: 'userLastName 2', count: 30 },
      ]} 
    />
    <p>Start editing to see some magic happen :)</p>
  </div>
);

render(<App />, document.getElementById('root'));

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Dmitry Belyaev, 2020-10-18
@WebDiamis

mport React from 'react';
import { render } from 'react-dom';

type ITableColumn<D extends Record<string, any>> = {
  property: string;
  format?: (value: any, item: D) => React.ReactNode | string | number;
  header?: any;
  footer?: any;
};

type ITable<T extends Record<string, any>, D extends Record<string, any>> = {
  isLoading?: boolean;
  columns: ITableColumn<D>[];
  rows: Array<T>;
};

type IContext<D extends Record<string, any>> = {
  rows: any;
  columns: ITableColumn<D>[];
};

const getColumns = <D extends Record<string, any>>(): ITableColumn<D>[] => [
  {
    property: 'name',
    format: (value, item) => {
      const { lastName } = item;
      return `${value} ${lastName}`;
    },
    header: 'heade',
    footer: 'footer'
  },
  {
    property: 'count',
    header: 'heade',
    footer: 'footer'
  }
]

interface AppProps { }
interface AppState {
  name: string;
}

const Table:React.FC<ITable> = ({ isLoading, columns, rows }) => {
  return <h1>table</h1>
}

const App = () => (
  <div>
    <Table 
      columns={getColumns()} 
      rows={[
        { name: 'userName 0', lastName: 'userLastName 0', count: 10 },
        { name: 'userName 1', lastName: 'userLastName 1', count: 20 },
        { name: 'userName 2', lastName: 'userLastName 2', count: 30 },
      ]} 
    />
    <p>Start editing to see some magic happen :)</p>
  </div>
);

render(<App />, document.getElementById('root'));

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question