1

I want to infer the number of keys of an object.

For an array, this works:

type LengthArray<T extends readonly any[]> = T["length"];
type Length = LengthArray<["ryan", 1, true, 90]>;
// Length is 4 :)

I'm trying to do this from an object:

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

I would need to know that in the above interface, the number of properties would be exactly 2, not "number".

At the end of the day, what I would most like to know is whether the object has no properties:

type LengthObject<T> = <?>

function infer<T>(o: T): LengthObject<T> extends 0 ? number : string {
    // ...
}
const r1 = infer({}); // r1 is number;
const r2 = infer({ name: "ryan" }); // r2 is string;
Ryan Izac
  • 13
  • 3

1 Answers1

1

Detecting if an object type T has no keys can be trivially done by checking if keyof T is never.

function infer<T>(o: T): keyof T extends never ? number : string {
    return null!
}
const r1 = infer({}); // r1 is number;
const r2 = infer({ name: "ryan" }); // r2 is string;

A general purpose solution to get the number of properties of an object type is a bit trickier. We can distribute over the keys of T and build a tuple which has an element for each property in T. The number of properties is now the length of the tuple.

type LengthObject<T, K extends keyof T= keyof T> = [K] extends [never]
  ? []
  : K extends K ? [0, ...LengthObject<Omit<T, K>>] : never

type Length = LengthObject<{ name: string; age: number }>["length"]
//   ^? type Length = 2

Note that both of these solutions might or might not behave unexpectedly when index signatures are involved.


Playground

Tobias S.
  • 21,159
  • 4
  • 27
  • 45
  • Hi, can you explain further what `K extends keyof T= keyof T` and `[0, ...LengthObject>]` do? – CM K Jan 19 '23 at 03:44
  • 1
    Oof, the number of steps to compute `LengthObject` scales *exponentially* with the number of keys, so things will start getting very slow with as few as 8 keys, and blow out the recursion limits completely with 9 or more keys. You might want to mention that. – jcalz Jan 19 '23 at 04:22
  • 1
    [This version](https://tsplay.dev/N5OM0W) should scale better, although it's doing something [very naughty](https://stackoverflow.com/a/55128956/2887218) to work around it. – jcalz Jan 19 '23 at 04:28
  • 2
    @jcalz from my exp, if we want to know number of props - smth is going wrong – captain-yossarian from Ukraine Jan 19 '23 at 09:35