TypeScript interface如何实现age/DOB二选一的属性声明
问题解答
错误原因
你编写的
age | DOB: Number | Date不符合TypeScript接口的语法规范,属性名位置不能直接使用联合类型声明,因此会直接抛出语法错误。
可以实现,正确实现方式如下
方案1:拆分接口+联合类型(最直观,无需额外工具类型)
先提取公共属性到基础接口,再分别定义仅携带age和仅携带DOB的子接口,最后将两个子接口合并为联合类型,同时通过设置互斥属性为never实现二选一校验:
// 公共属性基础接口 interface StudentBase { Name: string; // 注意类型定义用小写的string/number,不要用大写的String/Number包装类型 } // 仅携带age的子接口,DOB不允许存在 interface StudentWithAge extends StudentBase { age: number; DOB?: never; } // 仅携带DOB的子接口,age不允许存在 interface StudentWithDOB extends StudentBase { DOB: Date; age?: never; } // 最终的Student类型 type Student = StudentWithAge | StudentWithDOB;
效果验证
// 合法:仅携带age const s1: Student = { Name: "张三", age: 18 }; // 合法:仅携带DOB const s2: Student = { Name: "李四", DOB: new Date("2005-01-01") }; // 报错:不允许同时存在age和DOB const s3: Student = { Name: "王五", age: 18, DOB: new Date() };
方案2:通用互斥工具类型(适合多场景复用)
如果需要频繁使用二选一属性的场景,可以封装通用的XOR互斥工具类型:
// 通用互斥工具类型:T和U的属性只能存在其中一组 type XOR<T, U> = (T & { [K in keyof U]?: never }) | (U & { [K in keyof T]?: never }); interface StudentBase { Name: string; } // 公共属性 + age和DOB互斥 type Student = StudentBase & XOR<{ age: number }, { DOB: Date }>;
该方案的校验效果和方案1完全一致,复用性更强。
内容的提问来源于stack exchange,提问作者ram
相关产品推荐
相关产品推荐

