如何编写TypeScript条件类型确保数组元素icon属性统一存在或缺失?
实现数组元素icon属性的一致性约束(TypeScript)
你需要让函数接收的数组满足:要么所有元素都带icon属性且值为string,要么所有元素都完全不带icon属性,不能出现部分有、部分没有的情况。原代码里的Array<Item>做不到这点,因为Item允许icon可选,下面是两种可行的实现方式:
方案一:定义明确的互斥类型
先定义两种严格的元素类型,一种强制带icon,一种完全禁止icon,再让函数接收这两种类型的数组:
// 强制包含icon的元素类型 type ItemWithIcon = { title: string; icon: string; }; // 完全禁止包含icon的元素类型(icon设为never,无法赋值) type ItemWithoutIcon = { title: string; icon?: never; }; // 函数只能接收纯ItemWithIcon数组,或纯ItemWithoutIcon数组 function Func<T extends ItemWithIcon | ItemWithoutIcon>(items: T[]) { return items.map(item => item); }
测试验证
// ✅ 全部带icon,正常通过 Func([ { icon: 'home', title: 'Home' }, { icon: 'phone', title: 'Phone' }, { icon: 'user', title: 'User' }, ]); // ✅ 全部不带icon,正常通过 Func([ { title: 'Home' }, { title: 'Phone' }, { title: 'User' } ]); // ❌ 报错:部分元素无icon,不符合约束 Func([ { icon: 'home', title: 'Home' }, { icon: 'phone', title: 'Phone' }, { title: 'User' }, ]); // ❌ 报错:部分元素有icon,不符合约束 Func([ { icon: 'home', title: 'Home' }, { title: 'Phone' }, { title: 'User' } ]);
方案二:用泛型条件类型动态约束
如果不想拆分类型,可以用泛型条件类型,根据传入的元素类型自动约束整个数组的一致性:
type BaseItem = { title: string; icon?: string; }; // 动态判断:如果元素带icon,数组必须全是带icon的;否则全不带 type ConsistentItems<T extends BaseItem> = T extends { icon: string } ? Array<{ title: string; icon: string }> : Array<{ title: string; icon?: never }>; function Func<T extends BaseItem>(items: ConsistentItems<T>) { return items.map(item => item); }
这个方案里,ConsistentItems会自动根据你传入的第一个元素类型,强制整个数组保持相同的icon属性状态。
内容的提问来源于stack exchange,提问作者mikoloism
相关产品推荐
相关产品推荐

