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

如何在TypeScript中推断对象键数量及判断空对象?

TypeScript 推断对象键数量及空对象判断

问题场景

对于数组,我们可以通过索引访问length属性得到具体的长度类型:

type LengthArray<T extends readonly any[]> = T["length"];
type Length = LengthArray<["ryan", 1, true, 90]>;
// Length 类型为 4

但对对象使用类似思路时,无法得到具体的键数量,只会返回number类型:

type LengthObject<T> = Array<keyof T>["length"];
type Length = LengthObject<{ name: string; age: number }>;
// Length 类型为 number

最终需求是实现一个类型推断函数,判断对象是否无属性,返回对应的类型:

type LengthObject<T> = <?>

function infer<T>(o: T): LengthObject<T> extends 0 ? number : string {
    // ...
}
const r1 = infer({}); // r1 应为 number
const r2 = infer({ name: "ryan" }); // r2 应为 string

解决方案

方案1:直接判断空对象(无需计算键数量)

如果仅需判断对象是否为空,无需获取具体键数量,可以直接通过keyof T是否为never来判断——空对象的keyof结果是never,非空对象则为键的联合类型:

type IsEmptyObject<T> = keyof T extends never ? true : false;

function infer<T>(o: T): IsEmptyObject<T> extends true ? number : string {
  return Object.keys(o).length === 0 
    ? (0 as unknown as number) 
    : ('string' as unknown as string);
}

const r1 = infer({}); // 类型为 number
const r2 = infer({ name: "ryan" }); // 类型为 string

方案2:获取对象的具体键数量

如果确实需要获取对象键的具体数量,需要通过递归将对象的键转换为字面量元组(只有字面量元组的length会返回具体数值类型):

// 递归将对象键转换为元组
type TupleFromKeys<T> = keyof T extends infer K 
  ? K extends keyof T 
    ? [K, ...TupleFromKeys<Omit<T, K>>] 
    : [] 
  : [];

// 从元组获取长度
type LengthObject<T> = TupleFromKeys<T>["length"];

function infer<T>(o: T): LengthObject<T> extends 0 ? number : string {
  return Object.keys(o).length === 0 
    ? (0 as unknown as number) 
    : ('string' as unknown as string);
}

const r1 = infer({}); // 类型为 number
const r2 = infer({ name: "ryan" }); // 类型为 string

原理说明

  • 数组的length能返回具体数值,是因为字面量数组(如['a','b'])在TypeScript中会被推断为元组类型,元组的length是固定的字面量数值;而Array<keyof T>得到的是普通数组类型,其length属性类型为number。
  • 递归转换元组的思路是每次取出对象的一个键,将其加入元组,再移除该键后递归处理剩余对象,最终得到包含所有键的字面量元组,其length就是键的具体数量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 14:55:15