TypeScript如何限定对象键值范围且无需包含全部键?
问题:TypeScript限定对象键范围但无需强制包含全部键
用户定义了以下类型:
export const ABC= { A: 'A', B: 'B', C: 'C', } as const; export const DEF = { D: 'D', E: 'E', F: 'F', } as const; export type AbcTypes = (typeof ABC)[keyof typeof ABC]; export type DefTypes = (typeof DEF)[keyof typeof DEF];
需求是创建一个对象类型,其键只能是AbcTypes和DefTypes中的值,但无需强制包含所有键。最初编写的类型如下:
type MyNewDictionary = { [pKey in AbcTypes]: { [eKey in DefTypes]: { onClick: () => void; onCancel: () => void; } } };
但只设置部分键时,TypeScript会提示缺失其他属性,尝试Partial和keyof后问题依旧。
解决方案
你遇到的问题是因为原类型的索引签名是必选的,TypeScript会强制要求包含所有AbcTypes和DefTypes对应的键。要实现“限定键范围但无需全包含”,需要将索引签名改为可选,有两种实现方式:
方式一:直接在索引签名后添加?
将外层的AbcTypes索引和内层的DefTypes索引都标记为可选:
type MyNewDictionary = { [pKey in AbcTypes]?: { [eKey in DefTypes]?: { onClick: () => void; onCancel: () => void; } } };
这样无论是外层的A/B/C键,还是内层的D/E/F键,都可以选择性添加,不会因为缺失而报错。
方式二:嵌套使用Partial
如果更习惯用Partial工具类型,可以分别对两层对象进行包裹:
type MyNewDictionary = Partial<{ [pKey in AbcTypes]: Partial<{ [eKey in DefTypes]: { onClick: () => void; onCancel: () => void; } }> }>;
外层Partial让AbcTypes的键变成可选,内层Partial让DefTypes的键变成可选,效果和方式一完全一致。
为什么之前用Partial没效果?
如果只是直接给原类型套Partial<MyNewDictionary>,只会让外层的AbcTypes键变成可选,但内层的DefTypes键仍然是必选的——也就是说,只要你添加了某个外层键,就必须写全该键下所有D/E/F的内层键,这不符合你的需求。所以需要嵌套使用Partial来处理两层的可选性。
内容的提问来源于stack exchange,提问作者Unapedra
相关产品推荐
相关产品推荐

