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); // ❌ 整体参数类型不匹配
原理说明
NotEmptyObject<T>:利用TypeScript条件类型,判断T是否是无任何属性的空对象(Record<string, never>是TS中表示空对象的标准方式)。如果是空对象就返回never,直接排除空对象作为合法属性值的可能。- 递归泛型:
TObjectType<T>中嵌套的对象类型被限制为NotEmptyObject<TObjectType<T>>,递归逻辑确保所有层级的嵌套对象都不能是空对象,适配任意结构的对象。
内容的提问来源于stack exchange,提问作者user3765649
相关产品推荐
相关产品推荐

