Reputation: 1646
Is it possible to write a TypeScript type guard that checks if a given object is empty?
I'm able to do the opposite, i.e. write a type guard that checks if an object is non-empty (using lodash isEmpty here):
isNonEmpty<T>(object: T | {}): object is T {
return !_.isEmpty(object);
}
writeTextIfAny(param: { text: string } | {}): void {
if (isNonEmpty(param)) {
console.log(param.text);
}
}
However, when I try to reverse things, something goes wrong:
isEmpty<T>(object: T | {}): object is {} {
return _.isEmpty(object);
}
writeTextIfAny(param: { text: string } | {}): void {
if (!this.isEmpty(param)) {
// param is never, not { text: string }
}
}
Why is that?
Upvotes: 2
Views: 2079
Reputation: 11
You ought to be able to use !isNotEmpty(yourVar)
to achieve the behavior you want
Upvotes: 0
Reputation: 30959
In general, a TypeScript object type includes any object that has at least the specified properties. That means {}
is effectively the type of any object. So if your custom type guard claims that param
is not a {}
, then it is not a {text: string}
either, and you are left with never
. (In fact, T | {}
just simplifies to {}
, though maybe it shouldn't quite.)
I don't believe there's a way to write a type guard for an empty object. If you say more about how this came up, I might have more suggestions.
Upvotes: 6