Как задать дженерик для массива в объекте?

Подскажите пожалуйста как настроить верный дженерик (с ними я плохо знаком).

Суть в следующем:
есть компонент Table который принимает пропсы описанные в типе ITable.
пропс columns принимает массив в формате ITableColumn где в ключе formant.item является форматом переданным в компонент Table в пропсе rows.

Как указать верно дженерики?
online editor

Есть пример:
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'));
  • Вопрос задан
  • 97 просмотров
Решения вопроса 1
bingo347
@bingo347 Куратор тега TypeScript
Crazy on performance...
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'));
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы