TypeScript函数约束:第二个参数所有键需属第一个参数对象
如何让TypeScript函数的第二个参数所有键都属于第一个参数元素的属性?
我来帮你实现这个类型约束需求,我们可以利用TypeScript的泛型和递归条件类型,完美强制第二个参数的每一层键都必须是第一个参数数组元素的属性键。下面是完整的解决方案:
1. 先定义你的KeyValue类
class KeyValue { key: string; key2: string; constructor(k: string, k2: string) { this.key = k; this.key2 = k2; } }
2. 定义递归约束类型
首先我们需要一个递归类型,用来描述“所有层级的键都必须是目标类型的属性键”的对象结构:
// 递归类型:每一层的键都必须是T的属性键,值可以是数字或嵌套的同结构对象 type NestedKeyOf<T> = { [K in keyof T]?: NestedKeyOf<T> | number; };
这里的number对应你示例中的值类型,如果需要支持其他类型(比如字符串、布尔值),直接改成string | number | boolean这类联合类型即可。
3. 实现带类型约束的mapTo函数
接下来用泛型来绑定两个参数的类型关系:
function mapTo<T>(arr: T[], config: NestedKeyOf<T>) { // 这里可以编写你的实际业务逻辑,比如根据config映射数组元素 console.log('待映射数组:', arr); console.log('映射配置:', config); }
4. 测试效果
现在来验证你的需求场景:
合法调用(符合约束,TypeScript不会报错)
// 完全符合:key和key2都是KeyValue的属性 mapTo([new KeyValue('a', 'b')], { key: { key2: 1 } }); mapTo([new KeyValue('a', 'b'), new KeyValue('x', 'y')], { key: { key2: 1 } });
非法调用(不符合约束,TypeScript会直接报错)
// 错误:`invalidKey`不是KeyValue的属性 mapTo([new KeyValue('a', 'b')], { invalidKey: 1 }); // 错误:嵌套层的`invalidNestedKey`不是KeyValue的属性 mapTo([new KeyValue('a', 'b')], { key: { invalidNestedKey: 1 } });
核心原理说明
- 泛型
T会自动推导第一个参数数组的元素类型(比如KeyValue),keyof T会提取该类型的所有属性键列表。 - 递归类型
NestedKeyOf<T>确保了无论嵌套多少层,每一个键都必须属于T的属性键,完美匹配你需要的约束逻辑。 - 这个方案是完全类型安全的,在编译阶段就能拦截不符合约束的调用,不需要运行时检查。
内容的提问来源于stack exchange,提问作者Ravi Sevta
相关产品推荐
相关产品推荐

