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;
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With