You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现带不同类型引用的Columns<T>泛型类型定义

实现类型安全的嵌套子网格列泛型定义

要解决这个类型安全问题,核心是通过双泛型约束让子网格列类型从子项返回值自动推断,同时解除子模型与当前行模型的绑定限制。以下是具体实现方案:

1. 基础类型定义

先明确核心类型的结构,通过辅助工具类型提取数组元素类型,再定义普通列和子网格列:

// 辅助工具类型:提取数组的元素类型
type ArrayElement<T> = T extends (infer U)[] ? U : never;

// 普通列类型:绑定当前行的模型T
type Column<T> = {
  key: keyof T;
  label: string;
  // 可扩展其他通用属性,如 width、sortable 等
};

// 子网格列类型:T为当前行模型,N为子网格行模型
type SubgridColumn<T, N> = Column<T> & {
  type: 'subgrid';
  // 接收当前行数据,返回子模型数组
  subgridItems: (row: T) => N[];
  // 子列类型自动匹配子模型N的列定义
  subgridColumns: Columns<N>;
};

// 列定义联合类型:包含普通列和任意子网格列
type ColumnDefinition<T> = Column<T> | SubgridColumn<T, any>;

// 最终的列数组类型
type Columns<T> = ColumnDefinition<T>[];

2. 使用示例

以下示例展示了如何定义跨模型的子网格列,子模型无需与当前行模型有属性关联:

// 示例模型1:当前行模型
interface User {
  id: number;
  name: string;
  email: string;
}

// 示例模型2:子网格模型(与User无直接属性绑定)
interface UsageCountry {
  country: string;
  usageCount: number;
}

// 定义User的列数组,TypeScript自动推断子网格类型
const userColumns: Columns<User> = [
  { key: 'id', label: '用户ID' },
  { key: 'name', label: '用户名' },
  {
    key: 'email',
    label: '邮箱及使用地区',
    type: 'subgrid',
    // 返回UsageCountry[],TypeScript自动推断N为UsageCountry
    subgridItems: (user) => {
      // 可根据当前行数据生成子项,也可返回任意模型数组
      return [
        { country: '中国', usageCount: 120 },
        { country: '美国', usageCount: 80 }
      ];
    },
    // subgridColumns被自动约束为Columns<UsageCountry>,类型错误会直接报错
    subgridColumns: [
      { key: 'country', label: '国家/地区' },
      { key: 'usageCount', label: '使用次数' }
    ]
  }
];

关键特性说明

  • 自动类型推断:subgridColumns的类型会从subgridItems的返回数组中自动提取元素类型,无需手动指定子模型泛型参数
  • 类型安全:如果subgridColumns中出现子模型不存在的key,TypeScript会立即抛出类型错误
  • 无绑定限制:子模型可以是任意类型,不需要与当前行模型T有任何属性关联

内容的提问来源于stack exchange,提问作者Andyally

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 04:51:22