TypeScript中如何通过Wrapper属性关联对应姐妹接口类型?
实现仅传入包装类型属性即可约束对应姐妹接口参数的泛型函数
核心思路
要实现仅传入包装实例的属性就自动约束第二个参数,关键在于从属性值反向推断出原接口类型和属性键,再通过预定义的接口映射表找到对应的姐妹接口属性类型。
完整实现代码
// 1. 定义接口对的映射表,支持多组接口扩展 interface InterfacePairMap { A: B; B: A; // 可选:如果需要双向关联的话 } // 2. 包装类型定义(和你原代码一致) type WrapperType<T> = { extraProp: string } & T; // 3. 从包装类型的属性值中提取原接口和属性键的信息 type ExtractWrapperInfo<V> = V extends WrapperType<infer T>[infer P] ? { BaseInterface: T; PropKey: P } : never; // 4. 获取对应姐妹接口的同键属性类型 type RelatedPropType<V> = ExtractWrapperInfo<V> extends { BaseInterface: infer T; PropKey: infer P } ? P extends keyof InterfacePairMap[T] ? InterfacePairMap[T][P] : never : never; // 5. 目标泛型函数 declare function doSomething<V>(propValue: V, relatedProp: RelatedPropType<V>): void; // ------------------------------ // 测试示例 // ------------------------------ interface A { foo: string; bar: number; } interface B { foo: { id: string }; bar: boolean; } // 创建包装实例 const x: WrapperType<A> = { extraProp: "Hello", foo: "World", bar: 10, }; // 正确用法:第二个参数自动约束为B['foo']类型 doSomething(x.foo, { id: "test" }); // 错误用法:类型不匹配,TypeScript会抛出错误 // doSomething(x.foo, "wrong"); // 测试bar属性 doSomething(x.bar, true); // 正确,对应B['bar']的boolean类型 // doSomething(x.bar, "wrong"); // 错误
关键部分说明
- InterfacePairMap:用映射表管理所有接口对,后续新增接口对只需在这里添加条目,扩展性极强。
- ExtractWrapperInfo:通过条件类型的
infer关键字,从传入的属性值(比如x.foo)反向推断出它属于哪个原接口(A)以及对应的属性键(foo)。 - RelatedPropType:结合映射表,找到原接口对应的姐妹接口,再取出同键的属性类型,作为第二个参数的约束。
- doSomething函数:泛型参数
V捕获属性值的类型,自动推导第二个参数的类型约束,完全不需要传入包装实例或键名。
扩展支持多组接口
如果需要新增另一组接口对,比如C和D,只需:
- 定义接口
C和D - 在
InterfacePairMap中添加映射:
interface C { baz: Date; } interface D { baz: string; } interface InterfacePairMap { A: B; B: A; C: D; D: C; }
之后函数就能自动支持这组接口的属性约束。
内容的提问来源于stack exchange,提问作者Josh
相关产品推荐
相关产品推荐

