данных:
const items = [
{
id: '1',
joined: new Date('2021-03-15'),
revenue: 42_000,
revenueRate: 0.95,
username: 'Alice777',
},
{
id: '2',
joined: new Date('2020-08-26'),
revenue: 31_500,
revenueRate: 0.13,
username: 'Bob98',
},
//…
];
На их основе можно описать тип элемента:
type Item = {
id: string;
joined: Date;
revenue: number;
revenueRate: number;
username: string;
};
Но эти данные нужно выводить в HTML-таблицу. При этом, некоторые колонки нужно выравнивать по правому краю, а некоторые — кастомно форматировать (например, колонки с процентами или датами), и т.п.
Эти метаданные я решил описать в константе:
export const fields = [
{
align: 'right',
format: undefined,
key: 'id',
name: 'ID',
type: 'string',
},
{
align: undefined,
format: (date: unknown) => formatDate(date as Date),
key: 'joined',
name: 'Join Date',
type: 'date',
},
{
align: 'right',
format: undefined,
key: 'revenue',
name: 'Revenue',
type: 'number',
},
{
align: 'right',
format: (num: unknown) => formatNumber(num as number, 'percent'),
key: 'revenueRate',
name: 'Revenue Rate',
type: 'number',
},
{
align: undefined,
format: undefined,
key: 'username',
name: 'Username',
type: 'string',
},
] as const;
Константа соответствует типу:
type Field = {
align?: string;
format?: (val: FieldTypesDict[Field['type']]) => string;
key: string;
name: string;
type: keyof FieldTypesDict;
};
где FieldTypesDict — просто словарик со всеми возможными типами данных для таблицы:
type FieldTypesDict = {
date: Date;
number: number;
string: string;
//…
};
Но у константы проблема — в функцию форматирования прилетает значение с потерянным типом, хотя должен быть тип конкретного поля. Подскажите, плз, как получше это дело разрулить?
https://codesandbox.io/s/weathered-butterfly-y3ukm
https://codesandbox.io/s/dependable-table-30zjx
Я так понял, ключевой фрагмент это: type ColumnMap<T> = { [K in keyof T]: { label: string; name: K; renderer: (value: T[K]) => Renderable; }; }; ? Круто. Буду дальше курить твой пример. Благодарю!
🤘🏿
Обсуждают сегодня