如何定义仅包含满足特定条件对象的TypeScript类型?
TypeScript 基于条件约束类型的实现方案
针对你提出的三种场景,TypeScript 提供了不同的实现方式,下面逐一说明:
1. 约束对象包含指定键"x"
可以通过条件类型结合索引类型实现,仅保留包含目标键的对象类型:
// 泛型类型:仅当传入的 T 包含 x 属性时返回原类型,否则返回 never type X<T> = T extends { x: unknown } ? T : never; // 示例验证 type ValidObj = X<{ x: number; y: string }>; // 类型为 { x: number; y: string } type InvalidObj = X<{ y: string }>; // 类型为 never
2. 约束对象的k属性与w属性类型相等
需要利用 TypeScript 的双向类型相等判断(单向extends无法完全代表类型等价),先实现通用的类型相等工具,再结合条件类型:
// 实现类型相等判断工具:双向 extends 验证确保类型完全一致 type Equal<A, B> = A extends B ? (B extends A ? true : false) : false; // 约束对象的 k 和 w 属性类型相等 type KEqualsW<T> = T extends { k: infer K; w: infer W } ? (Equal<K, W> extends true ? T : never) : never; // 示例验证 type ValidPair = KEqualsW<{ k: number; w: number; name: string }>; // 类型为 { k: number; w: number; name: string } type InvalidPair = KEqualsW<{ k: number; w: string }>; // 类型为 never
3. 基于复杂函数逻辑约束类型
TypeScript 的类型系统是静态编译时的,无法直接调用运行时的ComplicatedFunction来判断类型,但存在两种处理情况:
- 如果函数逻辑可以转化为静态类型规则(比如判断属性范围、固定格式),可以在类型层面复现该逻辑:
// 示例:复现"属性age大于18"的函数逻辑 type AgeGreaterThan18<T> = T extends { age: infer A } ? (A extends number ? (A extends 19 | 20 | ... | 100 ? T : never) : never) : never; - 如果函数包含运行时动态逻辑(比如依赖外部数据、动态计算结果),则类型层面无法实现。因为编译时无法获取运行时的动态值,类型系统只能处理静态可推导的信息。
核心限制说明
TypeScript 类型系统不支持直接传入值参数,因为类型是编译时的抽象定义,而值是运行时的实体。所有类型判断必须基于静态类型信息,无法依赖运行时的动态逻辑。
内容的提问来源于stack exchange,提问作者Brian Duong
相关产品推荐
相关产品推荐

