TypeScript映射类型添加额外属性是否仅能使用交叉类型?
交叉类型不是在映射类型基础上新增额外属性的唯一实现方式,还有两种常用的可行方案,同时先说明你初始代码的语法报错原因,以及纠正需求实现的偏差:
报错原因
TS 语法层面不允许在同一个对象类型字面量内,同时书写映射类型语法([k in 联合类型])和固定属性声明,所以你直接加age: number的写法会触发报错。
替代实现方案
方案1:使用接口继承映射类型
你可以先把映射类型单独抽离,再用接口继承这个映射类型,之后直接在接口内声明额外属性即可:
type NameFields = { [k in "name" | "fullname"]: string }; interface Person extends NameFields { age: number; }
方案2:将固定属性纳入映射类型的键联合
把需要的固定属性键也放入映射类型的键联合中,配合条件类型给不同的键分配对应类型:
type Person = { [K in "name" | "fullname" | "age"]: K extends "age" ? number : string; };
需求实现修正提示
你最开始写的映射类型{ [k in "name" | "fullname"]: string }实际要求name和fullname两个属性同时必填,和你「必须定义name或fullname其中一个」的需求不符。如果需要二选一的逻辑,正确的实现方式如下:
// name与fullname二选一,同时必填age属性 type Person = ({ name: string } | { fullname: string }) & { age: number };
内容的提问来源于stack exchange,提问作者Cristian E.
相关产品推荐
相关产品推荐

