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

如何用TypeScript基于对象键动态生成Valid类型?

问题描述

我有如下动态数据:

const data = {games:{type: [], sport: [], category: []}}

当前我硬编码了类型:

type Valid = "type" & "sport" & "category"

请问如何基于Object.keys(data.games)动态生成type Valid,而非硬编码?

我尝试了以下写法:

type Valid = typeof Object.keys(data.games).join(' & ');

但出现错误:

Unexpected token, expected ";"

请帮助我实现type Valid的动态值生成。

解决方案

你之前的写法错误在于混淆了运行时代码和类型系统代码:

  • Object.keys()是运行时方法,TypeScript无法识别它返回的具体键名,只会将其类型判定为string[],无法直接用来构建精准类型。
  • join(' & ')是运行时字符串拼接操作,类型系统无法将其解析为有效的交叉类型语法。

正确的做法是利用TypeScript的keyof操作符和typeof类型查询,直接从数据的静态类型中提取键名:

const data = {games:{type: [], sport: [], category: []}};

// 提取data.games的键名联合类型
type ValidUnion = keyof typeof data.games;
// 此时ValidUnion的类型为 "type" | "sport" | "category"

// 如果确实需要交叉类型(而非联合类型),可以通过工具类型转换:
type UnionToIntersection<U> = 
  (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;

type Valid = UnionToIntersection<ValidUnion>;
// 此时Valid的类型为 "type" & "sport" & "category"

说明

  1. typeof data.games会获取data.games的静态类型:{ type: never[]; sport: never[]; category: never[]; }。
  2. keyof操作符会提取该类型的所有键名,得到对应的联合类型。
  3. 多数业务场景中,联合类型(|)已经能满足需求;如果必须使用交叉类型(&),再通过UnionToIntersection工具类型完成转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 04:05:18