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

TypeScript中如何通过泛型约束bar的键与foo的键一致?

实现TypeScript函数参数键的严格约束

你当前的写法无法生效,核心原因是foo被定义为Record<string, any>,这意味着keyof typeof foo等价于string,所以bar的Record<string, any>自然允许任意字符串键,TypeScript不会校验额外键。

通过泛型捕获foo的具体类型,可以实现严格的键约束,以下是两种常见方案:

方案1:强制bar包含foo的所有键,且无额外键

const myFn = <T extends Record<string, any>>(
    foo: T,
    bar: { [K in keyof T]: any } & { [key: string]: never }
) => {
    return { foo, bar }
}

测试效果

  • 合法调用(无错误):
    myFn({ one: 'noghint', two: 'nothing' }, { one: 'test', two: 'test' })
    
  • 传入额外键(触发错误):
    // 错误提示:对象文字可以只指定已知属性,“three”不在约束类型中
    myFn({ one: 'noghint', two: 'nothing' }, { three: 'nothing' })
    
  • 缺少foo中的键(触发错误):
    // 错误提示:缺少属性“two”,不满足约束类型
    myFn({ one: 'noghint', two: 'nothing' }, { one: 'test' })
    

方案2:允许bar包含foo键的子集,禁止额外键

如果不需要强制bar包含foo的所有键,仅要求bar的键都是foo已有的,可以用Partial修饰:

const myFn = <T extends Record<string, any>>(
    foo: T,
    bar: Partial<{ [K in keyof T]: any }> & { [key: string]: never }
) => {
    return { foo, bar }
}

测试效果

  • 合法调用(无错误):
    myFn({ one: 'noghint', two: 'nothing' }, { one: 'test' })
    
  • 传入额外键(依然触发错误):
    // 错误提示:“three”不在约束类型中
    myFn({ one: 'noghint', two: 'nothing' }, { three: 'nothing' })
    

原理说明

  • 泛型T会自动捕获foo传入的具体对象结构,而非宽泛的Record<string, any>;
  • { [K in keyof T]: any }约束bar的键必须是foo的键,且对应值可以是任意类型;
  • & { [key: string]: never }通过交叉类型禁止任何额外的字符串键——额外键的类型会被推断为never,与传入的实际值类型冲突,从而触发TypeScript错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 17:17:09