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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.