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

基于TypeScript条件类型实现深度选取方法的技术问询

嘿,我最近也在捣鼓TypeScript的条件类型做深度字段选取,刚好能帮到你!先理清楚咱们的需求:你想要一个DeepPick类型,能根据指定的深度路径,从数据模型里提取对应结构,然后让loadUser返回这个精确的类型对吧?

先拿你提到的User类型举个具体例子:

// 定义一个嵌套的User模型
type User = {
  id: string;
  name: {
    first: string;
    last: string;
  };
  posts: {
    id: number;
    title: string;
    content: string;
  }[];
};

// 期望调用loadUser后,返回只包含id、name.first、posts.id的结构
const user = loadUser<User, 'id' | 'name.first' | 'posts.id'>();
// 希望user的类型自动推导为:
// {
//   id: string;
//   name: { first: string };
//   posts: { id: number }[];
// }

你之前遇到的问题,大概率是直接用T[K]时,没办法处理'name.first'这种嵌套路径——因为T的键是'name',根本不存在'name.first'这个键,所以TypeScript会报错。另外数组类型的嵌套选取(比如posts.id)也容易被忽略,需要单独处理。

结合TypeScript的条件类型、模板字符串类型和递归,咱们可以实现一个完整的DeepPick:

// 辅助类型:判断是否是对象(排除函数)
type IsObject<T> = T extends object ? T extends Function ? false : true : false;

// 核心深度选取类型
type DeepPick<T, K> = 
  // 处理数组情况:如果T是数组,就对数组元素执行DeepPick,返回数组类型
  T extends (infer U)[] ? DeepPick<U, K>[] :
  // 如果是对象类型,继续处理路径
  IsObject<T> extends true ?
    // 情况1:K是T的直接键,直接提取该字段
    K extends keyof T ? { [P in K]: T[P] } :
    // 情况2:K是嵌套路径,用模板字符串拆分出第一级键和剩余路径
    K extends `${infer Key}.${infer Rest}` ?
      // 确保第一级键存在于T中,然后递归处理剩余路径
      Key extends keyof T ?
        { [P in Key]: DeepPick<T[Key], Rest> }
      : never // 路径不存在时返回never,触发类型检查
    : never
  : never; // 非对象类型直接返回never(避免基础类型的无效选取)

然后实现loadUser函数就很简单了:

function loadUser<T, K extends string>(): DeepPick<T, K> {
  // 这里替换成实际的异步请求逻辑,比如fetch后端接口
  // 类型断言只是为了绕过编译检查,实际返回要匹配DeepPick的结构
  return {} as DeepPick<T, K>;
}

现在测试一下,你会发现类型推导完全符合预期:

const user = loadUser<User, 'id' | 'name.first' | 'posts.id'>();

user.id; // 类型是string ✅
user.name.first; // 类型是string ✅
user.posts[0].id; // 类型是number ✅
// 如果尝试访问user.name.last,TypeScript会直接报错,因为我们没选取这个字段 ❌

几个需要注意的点:

  • 这个实现依赖TypeScript 4.1+的模板字符串类型,你用的typescript@next肯定支持;
  • 如果指定的路径不存在(比如'name.middle'),DeepPick会返回never类型,TypeScript会在编译阶段提醒你;
  • 目前只处理了对象和数组,如果你需要处理其他嵌套类型(比如Map、Set),可以扩展IsObject和递归逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:10:21