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

TypeScript中传入不同泛型参数的EdocReport实例至自定义Hook的问题

解决泛型类数组的TypeScript类型报错问题

问题背景

你定义了一个双泛型类EdocReport,在自定义Hook的入参类型TEdocReportsData中直接使用EdocReport[]时,TypeScript报错提示“Generic type 'EdocReport<TtypeDTO, TTypeFinalObject>' requires 2 type argument(s)”,但你的需求是在reports数组中放入泛型参数各不相同的EdocReport实例,比如EdocReport<DTOtype1, Type1>、EdocReport<DTOtype2, Type2>等。

解决方案

方案1:使用unknown作为泛型占位符(最简方案)

将TEdocReportsData中的reports字段类型改为EdocReport<unknown, unknown>[],既满足TypeScript的类型检查要求,又能容纳任意泛型参数的EdocReport实例:

type TEdocReportsData = {
  token: string;
  setIsLoading: (boolValue: boolean) => void;
  reports: EdocReport<unknown, unknown>[];
};

unknown是TypeScript类型安全的顶级类型,相比any更推荐,它会强制你在后续使用实例时进行必要的类型校验。

方案2:让Hook支持可变泛型参数(保留具体类型)

如果需要在Hook内部保留每个EdocReport实例的具体类型信息,可以将自定义Hook改为泛型,通过可变泛型参数匹配数组中的所有实例类型:

// 泛型Hook定义
export const useGetEdocReports = <T extends EdocReport<any, any>[]>(edocReportsData: {
  token: string;
  setIsLoading: (boolValue: boolean) => void;
  reports: T;
}) => {
  // 此处可获取每个report的具体类型,无需额外类型断言
  // 业务逻辑实现...
};

使用时TypeScript会自动推导数组中每个实例的泛型参数,无需手动指定:

useGetEdocReports({
  token: "token",
  setIsLoading: (boolValue) => setIsCustomLoading(boolValue),
  reports: [
    new EdocReport<DTOtype1, Type1>("address1", ["key1"], "NONE"),
    new EdocReport<DTOtype2, Type2>("address2", ["key2"], "fieldName"),
    new EdocReport<DTOtype3, Type3>("address3", ["key3"], (data) => data),
  ]
})

方案3:定义非泛型基接口/类(严谨类型约束)

如果所有EdocReport实例存在共享的方法或属性,可以先定义一个非泛型的基接口,让泛型类继承该接口,再用基接口类型作为数组元素类型:

// 定义非泛型基接口,声明所有实例共享的成员
interface IEdocReport {
  getAddress(): string;
  getQueryKey(): QueryKey;
}

// 泛型类实现基接口
export class EdocReport<TtypeDTO, TTypeFinalObject> implements IEdocReport {
  constructor(
    private _address: string,
    private _queryKey: QueryKey,
    private _sort: "NONE" | keyof TtypeDTO | ((dataArray: TtypeDTO) => TtypeDTO)
  ) {}

  getAddress(): string {
    return this._address;
  }

  getQueryKey(): QueryKey {
    return this._queryKey;
  }

  // 类型转换等业务逻辑...
}

// 修改入参类型为基接口数组
type TEdocReportsData = {
  token: string;
  setIsLoading: (boolValue: boolean) => void;
  reports: IEdocReport[];
};

这种方式适合需要在Hook中统一操作所有实例的场景,类型约束更严谨。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 02:35:09