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

如何构造要求至少含一个属性的TypeScript非空类型?

构造至少包含一个属性的TypeScript类型

针对你提出的需求——要求一个类型允许原可选属性类型的所有值,但排除空对象,有两种通用的实现方式,不需要手动枚举所有属性组合:

方法一:映射类型+交叉类型

通过映射类型将每个属性单独设为必填,再取联合类型后与原可选类型交叉,确保至少有一个属性存在:

type NotEmpty<T> = T extends Record<string, never> 
  ? never  // 处理T本身是空类型的极端情况
  : { [K in keyof T]-?: Pick<T, K> }[keyof T] & Partial<T>;

代码说明

  • { [K in keyof T]-?: Pick<T, K> }:遍历T的每个属性K,生成仅包含K且K为必填的类型
  • [keyof T]:取出上述所有类型的联合集合,得到所有"仅含单个必填属性"的类型
  • & Partial<T>:与原可选类型交叉,允许同时存在其他可选属性
  • 开头的条件判断用于处理T本身无任何属性的情况,此时返回never表示无合法值

使用示例

type T = {
  x?: number;
  y?: string;
  z?: number;
};

let a: NotEmpty<T> = { z: 1 }; // ✅ 正常通过
a = {}; // ❌ 报错:类型 '{}' 缺少至少一个必填属性
a = { x: 2, y: "hello" }; // ✅ 正常通过

方法二:利用Exclude简化实现

如果原类型T仅包含可选对象属性(不包含null、undefined等其他类型),可以用更简洁的写法:

type NotEmpty<T> = Exclude<T, {}>;

代码说明

原类型T因所有属性可选,{}是它的子类型。Exclude<T, {}>会直接从T中排除空对象类型,剩下的就是至少包含一个属性的合法值。

使用示例

type T = { x?: number; y?: string };
let b: NotEmpty<T> = { x: 1 }; // ✅ 正常通过
b = {}; // ❌ 报错:类型 '{}' 无法赋值给 'NotEmpty<T>'

这个写法更简洁,但要注意如果T的范围包含非对象类型(比如T = {x?: number} | null),需要额外调整,避免误排除其他合法类型。

内容的提问来源于stack exchange,提问作者Yevgeniy P

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 15:05:00