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

TypeScript中能否基于JS对象键定义类型?代码问题求助

问题解决方法

你的问题出在两个核心点:

  • 手动给fields添加了Partial<Record<keyof SomeThing, boolean>>类型注解,导致TypeScript丢失了a: true、b: false的字面量类型信息,只会将所有属性识别为boolean | undefined,无法区分具体的true/false值。
  • Partial会让SomeThing的所有键(包括未定义的c)都成为可选属性,所以keyof typeof fields会包含a、b、c,而c的类型是undefined。

修正方案

首先,移除fields的类型注解,并用as const断言保留字面量类型:

interface SomeThing {
    a: string
    b: string
    c: string
}

// 用const断言保留字面量类型,TypeScript会准确记录{a: true, b: false}
const fields = {
  a: true,
  b: false,
} as const;

然后调整ExtractFields类型,只提取F中值为true的键,并映射到T的对应类型:

// 先提取F中值为true的键名
type TrueKeys<F> = { [K in keyof F]: F[K] extends true ? K : never }[keyof F];

// 再从T中筛选这些键对应的类型
type ExtractFields<T, F> = Pick<T, TrueKeys<F>>;

type Result = ExtractFields<SomeThing, typeof fields>;
// Result类型为:{ a: string }

原理说明

  • as const会让对象的属性值被推断为字面量类型(true/false),且对象本身变为只读,TypeScript不会自动拓宽类型为boolean。
  • TrueKeys类型遍历F的所有键,将值为true的键保留,其余转为never,最后通过[keyof F]提取出所有非never的键名。
  • Pick<T, TrueKeys<F>>从SomeThing中筛选出这些键,得到最终需要的类型。

简化合并版

如果不想拆分类型,也可以合并成一个工具类型:

type ExtractFields<T, F> = Pick<
  T,
  { [K in keyof F]: F[K] extends true ? K : never }[keyof F]
>;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 09:19:59