MST

星途 面试题库

面试题:TypeScript交叉类型与泛型在复杂React组件架构中的深度协同

假设你正在构建一个React应用,有一个可复用的表格组件,该组件需要能够处理不同类型的数据,并且每列的展示逻辑也可能不同。请使用TypeScript的交叉类型与泛型来设计这个表格组件的类型系统,确保类型安全且易于扩展。要求详细描述设计思路,并编写关键部分的代码示例。
24.0万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 泛型定义数据类型:使用泛型 T 来表示表格的数据类型,这样可以确保表格能处理不同结构的数据。
  2. 交叉类型定义列配置:对于每一列,我们需要定义其展示逻辑等相关配置。通过交叉类型来组合不同的属性,以确保类型安全且易于扩展。例如,我们可以有一个基本的列配置类型,然后根据不同的需求扩展这个类型。
  3. 组件属性类型定义:使用泛型和交叉类型来定义表格组件接收的属性类型,包括数据和列配置。

关键代码示例

// 定义列的基本配置类型
type ColumnBase<T> = {
  title: string;
  key: keyof T;
};

// 定义列的展示逻辑扩展类型
type ColumnRender<T> = {
  render?: (value: T[keyof T], record: T) => React.ReactNode;
};

// 组合基本配置和展示逻辑扩展类型
type Column<T> = ColumnBase<T> & ColumnRender<T>;

// 定义表格组件接收的属性类型
type TableProps<T> = {
  dataSource: T[];
  columns: Column<T>[];
};

// 表格组件
import React from'react';

const TableComponent = <T>(props: TableProps<T>) => {
  const { dataSource, columns } = props;
  return (
    <table>
      <thead>
        <tr>
          {columns.map(column => (
            <th key={column.key}>{column.title}</th>
          ))}
        </tr>
      </thead>
      <tbody>
        {dataSource.map(record => (
          <tr key={record[columns[0].key]}>
            {columns.map(column => {
              const value = record[column.key];
              return (
                <td key={column.key}>
                  {column.render? column.render(value, record) : value}
                </td>
              );
            })}
          </tr>
        ))}
      </tbody>
    </table>
  );
};

export default TableComponent;

在上述代码中:

  1. ColumnBase<T> 定义了列的基本属性,title 用于显示列标题,key 用于指定数据对象中对应的属性名。
  2. ColumnRender<T> 定义了可选的 render 函数,用于自定义列的展示逻辑。
  3. Column<T> 通过交叉类型将 ColumnBase<T>ColumnRender<T> 组合起来,形成完整的列配置类型。
  4. TableProps<T> 定义了表格组件接收的属性类型,包括 dataSource(数据数组)和 columns(列配置数组)。
  5. TableComponent 是表格组件,根据传入的 dataSourcecolumns 渲染表格内容。如果列配置中有 render 函数,则使用该函数进行内容渲染,否则直接显示数据值。