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

TypeScript中基于键值元组生成CachedItems类型的实现疑问

TypeScript中基于键值元组生成CachedItems类型的实现疑问

你这个需求完全可以实现!先说说你之前写法的问题所在,再给你正确的实现思路~

为什么你的原写法没生效?

你原来的代码是先遍历元组索引生成数组类型,每个元素是单个键的Record,最后用[number]取出联合类型。但联合类型的对象意味着要么包含users,要么包含blacklist,要么包含something,而不是同时拥有所有键的完整对象——这就是为什么你要么报错,要么得到never类型的原因。

正确的实现方式

从TypeScript 4.1版本开始,我们可以利用**映射类型的键重映射(as关键字)**来完美实现这个需求。核心思路是遍历元组的索引,把每个索引对应的键(T[I])作为对象的属性名,同时取出对应位置的值类型(V[I])构建Map<string, V[I]>。

简洁版实现(推荐)

// 定义测试用的基础类型
type User = { id: string; name: string }
type Blacklist = { userId: string; reason: string }
type Something = { data: any }

// 核心类型实现
type CachedItems<T extends readonly string[], V extends readonly any[]> = {
  [I in keyof T as T[I]]: Map<string, V[I]>
};

测试验证

// 生成目标类型
type Result = CachedItems<['users', 'blacklist', 'something'], [User, Blacklist, Something]>;

/*
Result最终的类型完全符合你的预期:
{
  users: Map<string, User>;
  blacklist: Map<string, Blacklist>;
  something: Map<string, Something>;
}
*/

可选:强制元组长度一致

如果你想避免因为两个元组长度不匹配导致的潜在问题,可以给类型加上更严格的约束,强制T和V的长度必须相等:

type CachedItems<
  T extends readonly string[] & { length: V['length'] },
  V extends readonly any[]
> = {
  [I in keyof T as T[I]]: Map<string, V[I]>
};

这样如果传入的两个元组长度不一样,TypeScript会直接抛出错误,提前规避问题。

备注:内容来源于stack exchange,提问作者shadowplay1

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 15:38:01