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

TypeScript如何实现兼容泛型类的cast类型转换函数

问题原因

TS的泛型是编译期擦除的,不存在运行时表示。你写的C<string>属于类型层面的写法,不能作为值传入函数参数位置——作为值存在的C是泛型类的构造函数,本身不接受类型参数传参,所以会抛出ts(2635)错误。

改造方案

核心思路是把泛型参数的指定从「传入构造函数的位置」移动到「cast函数的泛型参数位置」,值层面始终传入原始构造函数用于instanceof运行时校验,泛型参数只在类型层面控制返回值类型,同时保留非泛型类的自动推导能力。

改造后的cast函数

type AnyConstructor = new (...args: any[]) => any;

export function cast<T>(obj: any, klass: AnyConstructor): T;
export function cast<T extends AnyConstructor>(obj: any, klass: T): InstanceType<T>;
export function cast(obj: any, klass: AnyConstructor) {
  if (!(obj instanceof klass)) {
    throw new Error(`Not an instance of ${klass.name}: ${obj.constructor.name}`);
  }
  return obj;
}

使用方式

  • 普通非泛型类和原有写法完全兼容,无需改动,TS会自动推导返回类型:
interface I {}
class C implements I {}

const i: I = {} as I;
// 自动推导c的类型为C
const c = cast(i, C);
  • 泛型类场景下,手动给cast传入目标泛型类型,值参数位置只传原始类构造函数,不要给类加<T>后缀:
interface I<T> {}
class C<T> implements I<T> {}

const i: I<string> = {} as I<string>;
// 手动指定返回类型为C<string>,c的类型符合预期,编译正常通过
const c = cast<C<string>>(i, C);
说明

该方案完全通用,不绑定任何特定类型层级:运行时的instanceof校验逻辑和原函数完全一致,仅在类型层面支持传入任意泛型类的实例类型作为返回值类型,符合不需要校验泛型参数内部属性、只要通过编译的要求,不需要额外使用as类型断言。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:54:08