TypeScript React 组件 - 根据动态标题验证表数据

问题描述 投票:0回答:1

我正在使用 TypeScript 开发自定义 React 表组件,我需要确保作为 props 传递的数据格式正确。该组件接受两个 props:

  • tableHeadings
    :对象数组,其中每个对象都有一个
    id (string)
    和一个
    title (string)
  • tableData
    :表示表格行的对象数组。每个对象都应具有与
    id
    中的
    tableHeadings
    值相对应的键。

这是 tableHeadings 和 tableData 的数据示例:

const tableHeadings = [
    {
        id: 'name',
        title: 'Name',
    },
    {
        id: 'job',
        title: 'Job',
    },
    {
        id: 'location',
        title: 'Color',
    },
    {
        id: 'country',
        title: 'Us',
    },
];

const tableData = [
    {
        name: 'Cy Ganderton',
        job: 'Quality Control Specialist',
        location: 'Canada',
        country: 'USA',
    },
    {
        name: 'Hart Hagerty',
        job: 'Desktop Support Technician',
        location: 'United States',
        country: 'USA',
    }
];

组件的使用方式如下:

<Table tableHeadings={tableHeadings} tableData={tableData} />

目标是验证

tableData
道具的结构是否与
tableHeadings
道具匹配。具体来说,
tableData
中的每个对象都应该具有与
id
中对象的
tableHeadings
值相匹配的键。

下图显示了
id
tableHeadings
字段与
tableData
对象的键之间的关系。

为了在 TypeScript 中定义组件及其类型,我编写了以下代码:

// inside Table component 
type TableHeadingType = {
    id: string;
    title: string
};

type TableDataType<K extends TableHeadingType[]> = {
    [Key in K[number]['id']]: string;
}; 


type TableProps<T extends TableHeadingType> = {
    tableData: TableDataType<T[]>[];
    tableHeadings:T[]
};

export const Table = <T extends TableHeadingType>({ tableHeadings, tableData }: TableProps<T>) => {
    const headers = tableHeadings.map((column, index) => {
        return (
            <th key={`headCell-${index}`} className={''}>
                {column.title}
            </th>
        );
    });

    const rows = !tableData?.length ? (
        <tr>
            <td colSpan={tableHeadings.length} className='text-center'>
                No data
            </td>
        </tr>
    ) : (
        tableData?.map((row, index) => {
            return (
                <tr key={`row-${index}`}>
                    {tableHeadings.map((column, index2) => {
                        const value = row[column.id as keyof typeof row] as string;
                        return <td key={`cell-${index2}`}>{value}</td>;
                    })}
                </tr>
            );
        })
    );

    return (
        <>
            <table className='content-table'>
                <thead>
                    <tr>{headers}</tr>
                </thead>
                <tbody>{rows}</tbody>
            </table>
        </>
    );
};

但是,根据

tableData
tableHeadings
的验证不起作用,并且也不会产生编译时或运行时错误

我该如何解决这个问题?

这里是代码游乐场的链接供参考:https://playcode.io/1812427

如果您可以帮助我解决 TypeScript React 组件中的验证问题,那将非常有帮助。

reactjs typescript
1个回答
0
投票

您可以将

id
字段类型从
string
更改为
enum
,然后使用此
enum
作为
key
处的
Record
tableData

enum HeadingIDEnum {
 name = 'name',
 job = 'job'
 ...
}

type TableHeadingType = {
    id: HeadingIDEnum;
    title: string
};

type TableDataType = Record<HeadingIDEnum, string>[]

https://www.typescriptlang.org/docs/handbook/enums.html

© www.soinside.com 2019 - 2024. All rights reserved.