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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 22:17:34