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

TypeScript泛型构建模板字面量时能否遍历嵌套对象?

实现TypeScript嵌套对象键的$select模板字面量

完全可以实现这个需求,通过组合TypeScript的泛型工具类型和递归模板字面量,就能生成符合要求的$select格式字符串类型。

核心实现步骤

  1. 提取值为对象类型的属性键:用KeysWithValsOfType工具类型筛选出目标类型中值为对象的属性名。
  2. 生成逗号分隔的键组合:通过递归模板字面量,生成嵌套对象键的所有单个或多个逗号分隔的组合。
  3. 拼接最终模板字面量:将属性名与对应的$select组合拼接成完整的查询字符串类型。

完整代码示例

// 提取类型T中值为U类型的属性键
type KeysWithValsOfType<T, U> = {
  [K in keyof T]: T[K] extends U ? K : never;
}[keyof T];

// 生成所有非空的逗号分隔键组合(支持单个或多个键)
type CommaSeparated<T extends string | number | symbol> = 
  T extends infer U extends string | number | symbol
    ? U | `${U},${CommaSeparated<Exclude<T, U>>}`
    : never;

// 生成最终的查询字符串类型
type SelectQuery<T> = {
  [K in KeysWithValsOfType<T, object>]: `${K}($select=${CommaSeparated<keyof T[K]>})`;
}[KeysWithValsOfType<T, object>];

测试用例

定义一个包含嵌套对象的类型:

type User = {
  id: number;
  name: string;
  person: {
    firstName: string;
    lastName: string;
    age: number;
  };
  address: {
    street: string;
    city: string;
  };
};

使用SelectQuery<User>会生成以下类型联合(仅展示部分示例):

// 包含所有合法的组合,比如:
"person($select=firstName)" | 
"person($select=firstName,lastName)" | 
"person($select=lastName,age)" | 
"address($select=street)" | 
"address($select=street,city)"

说明

  • CommaSeparated通过递归实现了所有可能的键组合,包括单个键和任意多个逗号分隔的键。
  • 最终的SelectQuery会自动遍历所有值为对象的属性,为每个属性生成对应的$select格式字符串。
  • 若嵌套对象的键数量较多,TypeScript可能触发递归深度限制,但常规业务场景下完全够用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 03:01:00