TypeScript无法推断键对应值类型,类型定义存在什么问题?
TypeScript类型定义问题分析与解决方案
你的类型定义核心问题是没有建立key和data的类型关联:
原代码中Payload<Es>的写法,用Es extends Record<infer K, infer V>做条件推断时,TypeScript会把K推断为Es所有键的联合类型(这里是"item.1" | "item.2"),V推断为所有值的联合类型(这里是0 | 1 | { ok: "Y", code: number })。最终trigger的类型变成了{ key: "item.1" | "item.2", data: 0 | 1 | { ok: "Y", code: number } },导致key和data完全独立——不管你选哪个key,data都能是任意值类型,自然达不到你期望的“选item.1时data对应特定类型”的效果。
正确的类型定义写法
要让key和data的类型绑定,需要用映射类型遍历每个键值对,生成对应的关联类型后再取联合:
type Payload<Es> = { trigger: { [K in keyof Es]: { key: K, data: Es[K] } }[keyof Es] }
原理说明
- 首先通过
[K in keyof Es]遍历Es的每个键K,为每个键生成专属的{ key: K, data: Es[K] }类型——比如对"item.1",生成{ key: "item.1", data: { ok: "Y", code: number } };对"item.2"生成{ key: "item.2", data: 1 | 0 }。 - 然后用
[keyof Es]把这些分散的类型提取出来,组成一个联合类型。
此时Payload<Evs>的实际类型为:
{ trigger: { key: "item.1", data: { ok: "Y", code: number } } | { key: "item.2", data: 1 | 0 } }
验证效果
修改后,TypeScript会自动根据key的值约束data的类型:
type Evs = { "item.1": { ok: "Y", code: number } "item.2": 1 | 0 } type Payload<Es> = { trigger: { [K in keyof Es]: { key: K, data: Es[K] } }[keyof Es] } // ✅ 合法:data类型与item.1匹配 const validPayload: Payload<Evs> = { trigger: { key: "item.1", data: { ok: "Y", code: 200 } } } // ❌ 报错:data类型与item.1不匹配 const invalidPayload: Payload<Evs> = { trigger: { key: "item.1", data: 1 } }
内容的提问来源于stack exchange,提问作者azzmi
相关产品推荐
相关产品推荐

