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
相关产品推荐
相关产品推荐

