如何在TypeScript中正确为含可选键组的对象定义类型?
解决TypeScript可选键组与@typescript-eslint/ban-types规则冲突的方案
你需要构建一个包含固定键、多组互斥完整替代键组,同时允许不包含任何替代键的TypeScript类型,但直接添加{}会触发lint规则。这里有一个无需忽略lint规则的可行方案:
使用Record<never, never>替代{}作为空对象类型选项,它和{}行为完全一致,但不会被@typescript-eslint/ban-types标记为违规。
修改后的类型定义如下:
type Props = { id: string } & ( { height: number; width: number } | { color: string } | Record<never, never> );
验证效果
- 合法场景:
- 仅包含固定键:
{ id: "user1" }符合类型要求 - 完整使用某一组替代键:
{ id: "user1", height: 50, width: 100 }或{ id: "user1", color: "#fff" }均合法
- 仅包含固定键:
- 非法场景:
- 单独使用替代键组中的部分键:
{ id: "user1", height: 50 }会被TypeScript报错(缺少width) - 同时使用多组替代键:
{ id: "user1", height: 50, color: "#fff" }会被TypeScript报错
- 单独使用替代键组中的部分键:
原理说明
Record<never, never>表示键的类型为never(不存在任何键),值的类型也为never,本质上就是空对象类型,和{}的语义完全等价,但属于@typescript-eslint/ban-types规则允许的合法写法,完美规避了lint报错问题。
如果你的lint规则对Record类型没有特殊限制,这就是最优雅的解决方案,无需忽略任何lint规则。
内容的提问来源于stack exchange,提问作者Thiago Pereira Maia
相关产品推荐
相关产品推荐

