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

如何编写泛型类型从对象提取指定key的fields.default类型?

TypeScript泛型类型ThingType实现问题

问题描述

现有对象:

const test = {
  thing1: {
    name: "one",
    fields: {
      thing1Field1: {
        default: "text",
      },
      thing1Field2: {
        default: 13,
      },
    },
  },
  thing2: {
    name: "two",
    fields: {
      thing2Field1: {
        default: 12,
      },
    },
  },
};

需要编写泛型类型ThingType,接收"thing1" | "thing2"作为参数,返回对应项中fields下各字段的default值类型,期望输出:

// ThingType<"thing1"> -
// {
//   thing1Field1: string;
//   thing1Field2: number;
// }

// ThingType<"thing2"> -
// {
//   thing2Field1: number;
// }

尝试以下代码时出现错误:"default"无法索引到typeof test[T]["fields"]

type ThingType<T extends keyof typeof test> = {
  [fieldName in keyof typeof test[T]["fields"]]: typeof test[T]["fields"][fieldName]["default"];
};

请问能否无需为test添加显式类型定义实现该泛型?若不能,该如何为test添加类型?

解决方案

无需显式类型定义的实现方式

错误原因是TypeScript默认类型推导无法确保typeof test[T]["fields"][fieldName]一定包含default属性,可通过条件类型+类型推断规避这个问题:

type ThingType<T extends keyof typeof test> = {
  [fieldName in keyof typeof test[T]["fields"]]: 
    typeof test[T]["fields"][fieldName] extends { default: infer U } 
      ? U 
      : never;
};

通过extends { default: infer U }明确检查字段项结构,提取default的类型U,即使TypeScript对原对象的类型推导不够精确,也能安全获取目标类型。

为test添加显式类型的实现方式

如果希望通过显式类型定义让代码逻辑更清晰,可先定义基础类型约束:

// 定义单个字段项的类型,强制包含default属性
type FieldItem<T> = {
  default: T;
};

// 定义每个Thing的结构
type Thing = {
  name: string;
  fields: Record<string, FieldItem<any>>;
};

// 为test指定精确的类型
const test: Record<"thing1" | "thing2", Thing> = {
  thing1: {
    name: "one",
    fields: {
      thing1Field1: {
        default: "text",
      },
      thing1Field2: {
        default: 13,
      },
    },
  },
  thing2: {
    name: "two",
    fields: {
      thing2Field1: {
        default: 12,
      },
    },
  },
};

此时原泛型代码即可正常工作,因为TypeScript已明确知道test[T]["fields"][fieldName]必然包含default属性:

type ThingType<T extends keyof typeof test> = {
  [fieldName in keyof typeof test[T]["fields"]]: typeof test[T]["fields"][fieldName]["default"];
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 18:50:25