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

TypeScript中能否将对象类型作为参数传递来封装通用Grid组件?

方案说明

TypeScript完全可以实现该需求,核心通过泛型组件配合动态依赖传递的方式就能完成Project-Grid桥接层的开发,把所有通用逻辑收敛到桥接层,业务侧仅需要传入对应场景的类型和依赖即可,不需要重复编写逻辑。

第一步:抽离公共类型约束

首先把三个可变依赖的公共结构抽成接口,作为泛型的约束条件,保证类型安全:

// 所有业务GridService需要实现的公共接口
interface IGridService {
  // 填入所有业务服务共有的方法签名,示例如下:
  fetchList?: (params: any) => Promise<any[]>
  saveData?: (data: any) => Promise<void>
}

// 所有Excel模板类的公共约束
interface IGridExcel {
  [key: string]: any
}

// 所有Grid入参Dto的公共约束
interface IGridDto {
  [key: string]: any
}

第二步:开发泛型桥接组件ProjectGrid

以下分别提供Angular(根据你提供的构造函数注入语法判断大概率是Angular项目)和React两种主流框架的实现:

Angular版本

首先定义注入Token用来接收业务侧传入的动态类:

import { InjectionToken, Inject, Component } from '@angular/core'
import { BaseGridComponent } from './base-grid.component' // 你的基础Grid组件
import { ExcelService, CommonService } from './common.service' // 公共服务

export const GRID_SERVICE = new InjectionToken<IGridService>('GRID_SERVICE')
// 接收构造函数类型
export const GRID_EXCEL_CLASS = new InjectionToken<new () => IGridExcel>('GRID_EXCEL_CLASS')
export const GRID_DTO_CLASS = new InjectionToken<new () => IGridDto>('GRID_DTO_CLASS')

实现泛型桥接组件:

@Component({
  selector: 'project-grid',
  template: `<base-grid [config]="gridConfig" (fileChange)="onFileChange($event)"></base-grid>`,
  standalone: true,
  imports: [BaseGridComponent]
})
export class ProjectGridComponent<
  TService extends IGridService,
  TExcel extends IGridExcel,
  TDto extends IGridDto
> {
  gridConfig = {} // 你的Grid通用配置

  constructor(
    private excelService: ExcelService,
    private commonService: CommonService,
    @Inject(GRID_SERVICE) public gridService: TService,
    @Inject(GRID_EXCEL_CLASS) private ExcelCls: new () => TExcel,
    @Inject(GRID_DTO_CLASS) private DtoCls: new () => TDto,
  ) {}

  // 所有业务Grid通用的逻辑全部收敛到这里,不需要重复编写
  onFileChange(evt: any) {
    /* 通用逻辑 */
    const header: string[] = Object.getOwnPropertyNames(new this.ExcelCls())
    /* 剩余通用逻辑 */
  }

  initialiseGrid(data: TDto) {
    /* 通用初始化逻辑 */
  }
}

React版本

如果是React项目可以直接通过props传递动态依赖,更简洁:

import BaseGrid from './base-grid'
import { ExcelService, CommonService } from './common.service'

type ProjectGridProps<TService, TExcel, TDto> = {
  gridService: TService
  ExcelCls: new () => TExcel
  DtoCls: new () => TDto
}

export function ProjectGrid<
  TService extends IGridService,
  TExcel extends IGridExcel,
  TDto extends IGridDto
>(props: ProjectGridProps<TService, TExcel, TDto>) {
  const { gridService, ExcelCls, DtoCls } = props

  const onFileChange = (evt: any) => {
    /* 通用逻辑 */
    const header: string[] = Object.getOwnPropertyNames(new ExcelCls())
    /* 剩余通用逻辑 */
  }

  const initialiseGrid = (data: TDto) => {
    /* 通用初始化逻辑 */
  }

  return <BaseGrid onFileChange={onFileChange} /* 其他配置传递 */ />
}

第三步:业务侧使用

业务场景的Grid组件只需要传入对应场景的三个类即可,不需要写任何重复逻辑:

Angular场景GridA示例

import { Component } from '@angular/core'
import { ProjectGridComponent, GRID_SERVICE, GRID_EXCEL_CLASS, GRID_DTO_CLASS } from './project-grid.component'
import { GridAService } from './grid-a.service'
import { GridAExcel } from './grid-a.excel'
import { GridADto } from './grid-a.dto'

@Component({
  selector: 'grid-a',
  template: `<project-grid></project-grid>`,
  standalone: true,
  imports: [ProjectGridComponent],
  providers: [
    { provide: GRID_SERVICE, useClass: GridAService },
    { provide: GRID_EXCEL_CLASS, useValue: GridAExcel },
    { provide: GRID_DTO_CLASS, useValue: GridADto }
  ]
})
export class GridAComponent {}

React场景GridA示例

import { ProjectGrid } from './project-grid'
import { GridAService } from './grid-a.service'
import { GridAExcel } from './grid-a.excel'
import { GridADto } from './grid-a.dto'

export function GridA() {
  return <ProjectGrid 
    gridService={new GridAService()}
    ExcelCls={GridAExcel}
    DtoCls={GridADto}
  />
}

方案优势

  • 逻辑仅需维护一份,后续迭代修改只需要调整ProjectGrid即可,不需要同步修改所有业务Grid
  • 完全类型安全,TS会自动推导所有传入依赖的类型,不会丢失类型提示和校验
  • 新增业务Grid仅需要传入三个对应类,开发效率可以提升80%以上

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 00:06:00