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

TypeScript如何编写按键生成对象子集的泛型函数类型

TypeScript 自动生成子Schema类型问题

问题场景

我有一个大型固定内容的键值对对象(命名为schema),该对象为自动生成,无法提前预知具体内容,未来还可能发生变更。
我需要编写一个TypeScript函数,同时满足以下两个要求:

  • 声明要从schema中提取的键时,输入键名的过程支持IDE自动补全
  • 根据传入的键从原schema生成子schema后,子schema的类型仅允许访问自身包含的键,访问不存在的键需要抛出编译错误

目前我只能单独满足其中一个要求,无法同时实现两个效果。

仅支持自动补全的初始实现

我最初写的版本可以实现键名自动补全,但无法对子schema做严格类型收窄,代码如下:

// 原schema对象
const schema = {
  key1: 'value1',
  key2: 'value2',
  keyX: 'valueX',
  keyY: 'valueY'
};

const makeSubSchema = <Schema extends { [key: string]: string }, Keys extends (keyof Schema)[]>(
  base: Schema,
  keys: Keys
) => {
  // 问题出在这里:Keys[number]类型没有被收窄到仅包含实际传入的键
  type SubSchema = Pick<Schema, Keys[number]>;

  const subSchema = keys.reduce<SubSchema>((acc, key) => {
    acc[key] = base[key];
    return acc;
  }, {} as SubSchema);

  return subSchema;
};

// 从schema自动生成合法键类型,用于约束键数组
type ValidKey = keyof typeof schema;

// 声明键数组为ValidKey[]类型,输入值时可以获得自动补全
const mykeys: ValidKey[] = ['keyX', 'keyY'];

const myschema = makeSubSchema(schema, mykeys);

// 正常:keyX在传入的键列表中
console.log('keyX', myschema.keyX);
// 预期报错:key1不在传入的键列表中,但当前版本不会触发编译错误
console.log('key1', myschema.key1);

这个版本的问题是:访问myschema.key1这类未传入的键时不会报错,TypeScript会判定原schema的所有键都是子schema的合法属性。

仅支持类型收窄的调整方案

我尝试通过as const修饰键数组来解决类型不收窄的问题:

const mykeys = ['keyX', 'keyY'] as const;

调整后访问myschema.key1确实可以正确抛出编译错误,但在数组中输入键名时会丢失自动补全能力。
目前看来第二种方案更接近正确结果,但我还没找到合适的写法,让传入的键既可以获得自动补全,又能让返回的子schema类型严格收窄到仅包含传入的键。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 23:39:21