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

如何指定泛型类型的泛型参数?TypeScript模型类型丢失问题

解决TypeScript泛型构建器保留模型自定义类型的问题

你的问题核心在于调用pickOnly后,构建器返回的模型类型被直接替换成了BaseModel,丢失了原自定义模型(比如CustomModel)的方法和成员。要解决这个问题,我们需要让构建器在调整属性类型的同时,保留原模型的类型结构。

解决方案步骤

  1. 定义类型替换工具:创建一个ReplaceModelAttributes类型,用来替换模型的属性泛型参数,同时保留原模型的所有自定义成员。
  2. 修改构建器方法:让pickOnly返回包含原模型类型变体的Builder,而不是直接返回BaseModel。

修改后的完整代码

/**
 * 基础数据模型类
 */
class BaseModel<T extends Record<string, any>> {
    private data: T = {} as T;

    getAttribute<K extends keyof T>(key: K): T[K] {
        return this.data[key];
    }
}

/**
 * 自定义数据模型类,包含自定义方法
 */
class CustomModel extends BaseModel<{ foo: string, bar: number }> {
    someMethod() { }
}

// 提取模型的属性类型
type GetAttributes<M extends BaseModel<any>> = M extends BaseModel<infer A> ? A : never;

// 挑选指定属性并将其他属性设为null
type PickAndNullifyOthers<T, K extends keyof T> = {
    [P in keyof T]: P extends K ? T[P] : null;
};

// 从构建器中提取模型类型
type GetModelFromBuilder<T> = T extends Builder<infer M> ? M : never;

// 替换模型的属性泛型参数,保留原模型的自定义成员
type ReplaceModelAttributes<M extends BaseModel<any>, A extends Record<string, any>> = 
    M extends BaseModel<infer _> 
        ? { new(): Omit<M, keyof BaseModel<any>> & BaseModel<A> } 
        : never;

/**
 * URL构建器类,支持挑选模型的特定属性
 */
class Builder<T extends BaseModel<any>> {
    pickOnly<K extends keyof GetAttributes<T>>(key: K): Builder<InstanceType<ReplaceModelAttributes<T, PickAndNullifyOthers<GetAttributes<T>, K>>>> {
        return {} as any;
    }
}

测试使用示例

const wrapper = new Builder<CustomModel>()
    .pickOnly('foo'); // 仅挑选foo属性,其他属性设为null

const model = {} as GetModelFromBuilder<typeof wrapper>;

const fooResult = model.getAttribute('foo'); // 类型:string
const barResult = model.getAttribute('bar'); // 类型:null
model.someMethod(); // 不再报错,保留了CustomModel的方法

原理说明

  • ReplaceModelAttributes类型通过条件类型,提取原模型的非BaseModel成员(比如someMethod),并将其与替换了属性泛型的BaseModel<A>合并,确保原模型的自定义方法不会丢失。
  • InstanceType将构造函数类型转换为实例类型,符合Builder泛型对BaseModel子类实例的要求。
  • 修改后的pickOnly方法返回的Builder泛型类型,是原自定义模型的变体,既调整了属性类型,又保留了所有自定义成员。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 03:27:26