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

TypeScript泛型接口条件属性:基于类型参数添加特定属性

解决方案:基于泛型参数条件添加属性

你可以通过**交叉类型(Intersection Types)结合条件类型(Conditional Types)**实现需求,核心思路是将泛型接口的基础属性与条件触发的额外属性合并,仅当泛型参数匹配指定类型时才添加额外属性。

实现代码示例

先定义基础类型:

interface A {
    IA: string;
}

interface B {
    IB: string;
}

// 定义G的核心属性集合
type GBase<T> = {
    IG: string;
    Parent: T;
};

// 定义条件触发的额外属性:仅当T属于A类型时包含prop1
type GExtra<T> = T extends A ? { prop1: string } : {};

// 合并核心属性与条件属性,得到最终的G<T>
type G<T> = GBase<T> & GExtra<T>;

验证效果

  • 当泛型参数为A时,G<A>会自动包含prop1:

    const gA: G<A> = {
        IG: "generic-g",
        Parent: { IA: "a-instance" },
        prop1: "extra-property" // 类型检查正常通过
    };
    
  • 当泛型参数为其他类型(如B)时,G<B>不会包含prop1:

    const gB: G<B> = {
        IG: "generic-g",
        Parent: { IB: "b-instance" }
        // 若强行添加prop1会触发类型错误,符合预期
    };
    

进阶:严格匹配类型(排除子类型)

如果需要仅当T完全等于A时才添加属性(排除A的子类型),可以调整条件类型为双向判断:

type GExtra<T> = [T] extends [A] ? [A] extends [T] ? { prop1: string } : {} : {};

比如存在A的子类型时:

interface AChild extends A {
    extra: string;
}

// G<AChild>不会包含prop1,因为AChild是A的子类型但不等于A
const gChild: G<AChild> = {
    IG: "generic-g",
    Parent: { IA: "child", extra: "more" }
    // 添加prop1会触发类型错误
};

替代方案:接口继承结合条件类型

如果偏好使用接口而非类型别名,也可以通过继承条件类型实现,但这种方式会生成可选的never类型属性(非A类型时prop1为可选的never,无法赋值但类型中会存在该属性):

interface G<T> {
    IG: string;
    Parent: T;
    prop1?: T extends A ? string : never;
}

这种方式不如交叉类型直观,推荐优先使用交叉类型的实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 23:21:19