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

TypeScript泛型类型限制:禁止嵌套对象中包含空对象

问题:用TypeScript泛型类型禁止对象嵌套空对象

现有如下对象:

const obj = {
    key1: { key2: 'string 1', key3: 'string 2', key4: {} },
    key5: { key6: 'string 4' },
    key7: 'string 5',
    key8: 'string 6',
};

需要实现一个泛型TypeScript类型,限制对象中不能包含空对象(示例中的key4: {}应触发TypeScript错误),同时允许属性值为string、(arg: string) => string或嵌套的合规对象,且无需编写JavaScript代码,仅通过类型声明实现。

当前已有的基础类型声明如下:

export type TObjectType<T> = {
  [key: string]: string | ((arg: string) => string) | TObjectType<T>;
};

const exampleFn = <T>(obj: TObjectType<T>):TObjectType<T> => {
    return obj;
};

解决方案

可以通过添加空对象判断类型,结合递归泛型实现需求,完整代码如下:

// 定义类型:如果传入的是空对象则返回never,否则返回原类型
type NotEmptyObject<T> = T extends Record<string, never> ? never : T;

// 修改后的泛型类型:嵌套对象必须是非空的
export type TObjectType<T> = {
  [key: string]: string | ((arg: string) => string) | NotEmptyObject<TObjectType<T>>;
};

// 示例函数无需修改
const exampleFn = <T>(obj: TObjectType<T>): TObjectType<T> => {
  return obj;
};

效果验证

当传入包含空对象的对象时,TypeScript会直接报错:

const obj = {
  key1: { key2: 'string 1', key3: 'string 2', key4: {} }, // ❌ 此处触发错误:类型 '{}' 不能赋值给类型 'string | ((arg: string) => string) | NotEmptyObject<TObjectType<{}>>'
  key5: { key6: 'string 4' },
  key7: 'string 5',
  key8: 'string 6',
};

exampleFn(obj); // ❌ 整体参数类型不匹配

原理说明

  1. NotEmptyObject<T>:利用TypeScript条件类型,判断T是否是无任何属性的空对象(Record<string, never>是TS中表示空对象的标准方式)。如果是空对象就返回never,直接排除空对象作为合法属性值的可能。
  2. 递归泛型:TObjectType<T>中嵌套的对象类型被限制为NotEmptyObject<TObjectType<T>>,递归逻辑确保所有层级的嵌套对象都不能是空对象,适配任意结构的对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 19:00:58