OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

deep keyof of a nested object in typescript

  • Thread starter Thread starter IncognitoUser
  • Start date Start date
I

IncognitoUser

Guest
I want to create a custom table. The prop in the cell and footer in createColumnHelper function should return the correct object key/type instead of any.

For example, I have a nested object progress in my DATA. Or if not an object, it also should return the correct type.

I attached screenshots of how I see in the IDE

Helper.ts

Code:
import { ReactElement } from "react";

export type Column<T> = {
  header: string | (() => ReactElement);
  accessor: (row: T) => any;
  cell?:(prop: any) => ReactElement | string;
  footer?: (prop: any) => ReactElement | string;
};

export const createColumnHelper = <T>() => {
  return {
    accessor: (
      accessor: keyof T | ((row: T) => any),
      column: {
        header: string | (() => ReactElement);
        cell?: (prop: any) => ReactElement | string;
        footer?: (prop: any) => ReactElement | string;
      }
    ) => {
      return {
        header: column.header,
        accessor: (row: T) => (typeof accessor === "function" ? accessor(row) : row[accessor]),
        cell: column.cell,
        footer: column.footer,
      } as Column<T>;
    }
  };
};

TableComponents.tsx

Code:
import React from "react";
import { createColumnHelper } from "./columnHelper";

type Person = {
  firstName: string
  lastName: string
  age: number
  visits: number
  status: string
  progress: {
    ok?: number;
    no?: string
  }
}

const DATA: Person[] = [
  {
    firstName: 'tanner',
    lastName: 'linsley',
    age: 24,
    visits: 100,
    status: 'In Relationship',
    progress: {
      ok: 50
    },
  },
  {
    firstName: 'tandy',
    lastName: 'miller',
    age: 40,
    visits: 40,
    status: 'Single',
    progress: {
      no: 'bad'
    },
  },
]

const columnHelper = createColumnHelper<Person>();

const columns = [
  columnHelper.accessor(
    'firstName', {
    header: 'First Name',
    cell: val => val,
  }),
  columnHelper.accessor(
    'progress', {
      header: 'Progress',
      cell: prop => prop.ok,
    }),
  columnHelper.accessor(row => row, {
    header: () => <span>Age</span>,
    cell: prop => <span>{prop.age}</span>,
  }),
];

const TableComponent: React.FC = () => {
  return (
    <table>
      <thead>
      <tr>
        {columns.map((column, index) => (
          <th key={index}>
            {typeof column.header === "function" ? column.header() : column.header}
          </th>
        ))}
      </tr>
      </thead>
      <tbody>
      {DATA.map((row, rowIndex) => (
        <tr key={rowIndex}>
          {columns.map((column, colIndex) => (
            <td key={colIndex}>
              {column.cell ? column.cell(column.accessor(row)) : column.accessor(row)}
            </td>
          ))}
        </tr>
      ))}
      </tbody>
      <tfoot>
      <tr>
        {columns.map((column, index) => (
          <td key={index}>
            {column.footer ? column.footer({ column }) : null}
          </td>
        ))}
      </tr>
      </tfoot>
    </table>
  );
};

export default TableComponent;

enter image description here enter image description here

<p>I want to create a custom table. The prop in the cell and footer in createColumnHelper function should return the correct object key/type instead of any.</p>
<p>For example, I have a nested object progress in my DATA. Or if not an object, it also should return the correct type.</p>
<p>I attached screenshots of how I see in the IDE</p>
<p>Helper.ts</p>
<pre><code>import { ReactElement } from "react";

export type Column<T> = {
header: string | (() => ReactElement);
accessor: (row: T) => any;
cell?:(prop: any) => ReactElement | string;
footer?: (prop: any) => ReactElement | string;
};

export const createColumnHelper = <T>() => {
return {
accessor: (
accessor: keyof T | ((row: T) => any),
column: {
header: string | (() => ReactElement);
cell?: (prop: any) => ReactElement | string;
footer?: (prop: any) => ReactElement | string;
}
) => {
return {
header: column.header,
accessor: (row: T) => (typeof accessor === "function" ? accessor(row) : row[accessor]),
cell: column.cell,
footer: column.footer,
} as Column<T>;
}
};
};
</code></pre>
<p>TableComponents.tsx</p>
<pre><code>import React from "react";
import { createColumnHelper } from "./columnHelper";

type Person = {
firstName: string
lastName: string
age: number
visits: number
status: string
progress: {
ok?: number;
no?: string
}
}

const DATA: Person[] = [
{
firstName: 'tanner',
lastName: 'linsley',
age: 24,
visits: 100,
status: 'In Relationship',
progress: {
ok: 50
},
},
{
firstName: 'tandy',
lastName: 'miller',
age: 40,
visits: 40,
status: 'Single',
progress: {
no: 'bad'
},
},
]

const columnHelper = createColumnHelper<Person>();

const columns = [
columnHelper.accessor(
'firstName', {
header: 'First Name',
cell: val => val,
}),
columnHelper.accessor(
'progress', {
header: 'Progress',
cell: prop => prop.ok,
}),
columnHelper.accessor(row => row, {
header: () => <span>Age</span>,
cell: prop => <span>{prop.age}</span>,
}),
];

const TableComponent: React.FC = () => {
return (
<table>
<thead>
<tr>
{columns.map((column, index) => (
<th key={index}>
{typeof column.header === "function" ? column.header() : column.header}
</th>
))}
</tr>
</thead>
<tbody>
{DATA.map((row, rowIndex) => (
<tr key={rowIndex}>
{columns.map((column, colIndex) => (
<td key={colIndex}>
{column.cell ? column.cell(column.accessor(row)) : column.accessor(row)}
</td>
))}
</tr>
))}
</tbody>
<tfoot>
<tr>
{columns.map((column, index) => (
<td key={index}>
{column.footer ? column.footer({ column }) : null}
</td>
))}
</tr>
</tfoot>
</table>
);
};

export default TableComponent;
</code></pre>
<p><a href="https://i.sstatic.net/YApu04x7.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/YApu04x7.png" alt="enter image description here" /></a>
<a href="https://i.sstatic.net/yM6rpv0w.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/yM6rpv0w.png" alt="enter image description here" /></a></p>
 

Latest posts

Top