为何TypeScript的keyof操作符会获取字面量类型的非枚举继承属性?
问题原因与解决方案
核心原因
你遇到的问题和in操作符无关,根源在于对keyof操作符的作用对象理解有误:
Item['type']对应的是ItemType,也就是'itemTypeA' | 'itemTypeB',这是字符串字面量联合类型,所有字符串字面量类型都是string的子类型。keyof作用于类型时,对于字符串字面量类型,它返回的是keyof string——也就是string原型链上所有的属性和方法名(比如toString、charAt、charCodeAt等),而非你预期的联合类型字面量成员。
这就是TypeScript要求你的对象包含这些继承属性,最终导致类型不匹配错误的原因。
解决方案
如果想要遍历联合类型的字面量成员,直接用联合类型本身作为映射的键即可,不需要添加keyof:
'use strict'; type Value = 1 | 2 ; type Owner = 'ownerA' | 'ownerB'; type ItemType = 'itemTypeA' | 'itemTypeB'; type Item = { type: ItemType; owner: Owner; value: Value; }; // 将 [m in keyof Item[k]] 修改为 [m in Item[k]] type AnotherType = { [k in keyof Item]: null | { [m in Item[k]]: number; }; }; const v: AnotherType = { type: { itemTypeA: 0, itemTypeB: 1 }, owner: { ownerA: 0, ownerB: 1 }, value: null, }; console.log(v);
修改后,[m in Item[k]]会直接遍历Item[k]对应的联合类型的每个字面量成员,生成符合预期的键值对结构,类型检查即可通过。
内容的提问来源于stack exchange,提问作者d.k
相关产品推荐
相关产品推荐

