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

如何基于嵌套对象与字符串字面量数组生成TypeScript复合类型

TypeScript复合类型生成解决方案:嵌套对象与指定键的拼接类型

需求描述

基于嵌套对象和字符串字面量数组生成复合类型,要求:

  • 包含字面量数组中列出的键与其子键拼接后的结果(如foo对应foo.a、foo.b)
  • 保留未在数组中的原对象键(如bar)

示例代码:

const data = {
  foo: {
    a: 1,
    b: 'b',
  },
  bar: { c: () => {} },
  baz: { d: 'test', e: 42 },
};
const literals = ['foo', 'baz'] as const satisfies readonly (keyof typeof data)[];

/** 目标实现MagicFunction */
type magicOutput = MagicFunction<typeof data, typeof literals>;

/** 期望输出类型 */
type expectedOutput = 'foo.a' | 'foo.b' | 'bar' | 'baz.d' | 'baz.e';

遇到的问题

已实现仅支持单个字符串字面量的SemiMagicFunction,但生成目标类型需硬编码数组条目,无法随literals数组变更自动更新。尝试使用Keys[number]时,Object[Keys[number]]始终返回never,需要可行的TypeScript解决方案。

解决方案

通过分布式条件类型和模板字面量类型实现自动生成目标类型,无需硬编码数组条目:

type MagicFunction<T extends Record<string, object>, K extends readonly (keyof T)[]> = 
  // 保留未在字面量数组中的原对象键
  Exclude<keyof T, K[number]> | 
  // 处理字面量数组中的键,拼接其子键为联合类型
  { [Key in K[number]]: `${Key & string}.${keyof T[Key] & string}` }[K[number]];

原理说明

  1. Exclude<keyof T, K[number]>:筛选出原对象中不在字面量数组内的键,直接作为类型成员保留。
  2. 分布式拼接逻辑:
    • 遍历字面量数组中的每个键Key,生成Key.SubKey格式的模板字面量类型
    • 通过[K[number]]索引访问实现分布式类型,将所有拼接结果合并为联合类型

验证测试

type magicOutput = MagicFunction<typeof data, typeof literals>;
// 类型等价于:'foo.a' | 'foo.b' | 'bar' | 'baz.d' | 'baz.e'

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 11:29:55