Reputation: 146000
I need to find a way to check if a typescript interface has one or more properties (property names are unknown) at compile time.
So for example given the following definitions:
export type Cat = {};
export type Dog = { barking: boolean };
I need a conditional type HasAnyProperties<T>
which will give me:
type catHasProperties = HasAnyProperties<Cat>; // false (because Cat is {})
type dogHasProperties = HasAnyProperties<Dog>; // true (because Dog has one or more properties)
To be clear I do not want:
Object.keys(obj).length
(this is a runtime check)This may seem like an odd request, but what I'm actually doing is first filtering a type after which I need to know if anything was left over. I then use that value to optionally add a new property on a mapped type. But that's the easy part!
The following attempts don't work:
// This always returns true
type HasAnyProperties<T> = T extends { [key: string]: any } ? true : false;
It would be a lot easier if I knew the names of the properties, but I don't.
My guess if this is possible is that it will look something like RequireAtLeastOne.
Upvotes: 0
Views: 840
Reputation: 146000
Turns out it's as simple as this:
export type HasAnyProperties<T> = {} extends T ? false : true;
At least for my case. If anyone with a similar need finds issues with this please comment or add a new answer.
Upvotes: 2