You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现TS工具类型:必选属性+全选或全不选可选属性

解决TypeScript RequiredAndAllOrNothing工具类型的问题

你的问题出在:当用Required<R> & (Required<S> | Record<string, never>)时,Record<string, never>和Required<R>交叉后得到的类型本质上就是Required<R>,TypeScript的结构类型系统允许对象包含额外属性,所以只填部分S属性的对象依然会被判定为符合Required<R> & Record<string, never>的类型,不会触发错误。

正确的实现需要在“不设置S属性”的分支里,明确禁止出现S的任何属性,而不是用空对象类型。具体写法如下:

type RequiredAndAllOrNothing<R, S> = Required<R> & (Required<S> | { [K in keyof S]?: never });

原理说明

  • Required<R>确保R的所有属性必须存在且为必填;
  • Required<S>分支要求S的所有属性必须全部设置;
  • { [K in keyof S]?: never }分支要求S的所有属性要么完全不存在,要么其类型为never(即无法赋值任何有效值),这样只要对象包含S的任意一个属性且有值,就会和这个类型冲突,从而被TS拦截。

验证示例

type Example = RequiredAndAllOrNothing<
  { aaaa: number; bbbb: boolean; cccc: boolean},
  { dddd: number; eeee: boolean; ffff: boolean }
>;

// ✅ 符合要求:仅包含R的所有属性
const x: Example = { aaaa: 1, bbbb: true, cccc: false };

// ✅ 符合要求:包含R和S的所有属性
const y: Example = { aaaa: 1, bbbb: true, cccc: false, dddd: 1, eeee: true, ffff: false };

// ❌ 不符合要求:仅设置了S的部分属性,类型报错
const z: Example = { aaaa: 1, bbbb: true, cccc: false, dddd: 1 };

修正你的AllOrNothing类型

你之前的AllOrNothing<T>其实也存在同样的潜在问题(测试部分属性时会失效),正确的写法应该是:

type AllOrNothing<T> = Required<T> | { [K in keyof T]?: never };

内容的提问来源于stack exchange,提问作者v-moe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 12:05:43