TypeScript:如何实现函数参数对象可包含0个或多个指定键
问题描述
我想要为一个函数添加类型定义,该函数接受一个包含特定键的对象,但希望开发者可以不提供这些键中的部分键,这样当使用未提供的特定键时,我可以抛出错误。
不过我无法实现不要求所有键都存在的类型定义,我的代码如下:
type Keys = "One" | "Two" | "Three" export const getConfig = ( key: Keys, config: { [key in Keys]: AnotherType; } ) => { if (!config[key]) { throw new Error(`Could not find config.`); } return config[key]; };
我希望函数可以这样调用:
getConfig('One', { One: {}, Three: {} })
但这样会出现如下错误:
Property 'Two' is missing in type
我尝试过各种undefined的组合,但都无法解决问题。
当前的临时解决方案如下:
getConfig('One', { One: {}, Two: null as unknown as any, Three: {} })
但这种方式的开发者体验(DX)非常差……请问如何解决这个问题?
解决方案
你需要让config的类型支持部分键可选,同时强制保证传入的key对应的键必须存在于config中。可以通过TypeScript的泛型和交叉类型实现这个约束:
type Keys = "One" | "Two" | "Three"; type AnotherType = {}; // 替换为你的实际类型 export const getConfig = <K extends Keys>( key: K, config: Partial<Record<Keys, AnotherType>> & Record<K, AnotherType> ) => { const value = config[key]; if (!value) { throw new Error(`Could not find config for key: ${key}`); } return value; };
代码说明
Partial<Record<Keys, AnotherType>>:将所有Keys中的键设为可选,允许开发者只传入需要的部分键。& Record<K, AnotherType>:通过交叉类型强制要求config必须包含当前传入的key对应的键,避免调用时传入不包含目标key的对象。- 泛型
K:捕获具体传入的key值,让TypeScript能精准校验config的结构。
效果验证
- 合法调用(目标key存在):
// 类型校验正常通过 getConfig('One', { One: {}, Three: {} }); getConfig('Two', { Two: {} }); - 非法调用(目标key不存在):
// 触发类型错误:Property 'Two' is missing in type '{ One: {}; }' but required in type 'Record<"Two", AnotherType>' getConfig('Two', { One: {} });
这种方案既保留了类型安全,又允许开发者灵活传入部分键,同时运行时的错误抛出逻辑依然生效。
内容的提问来源于stack exchange,提问作者lpetrucci
相关产品推荐
相关产品推荐

