kremerd
kremerd

Reputation: 1646

Type Guard for empty object

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

Answers (3)

Alessign
Alessign

Reputation: 798

Simple solution:

guard (self.object != nil) else { return }

Upvotes: -2

sce415
sce415

Reputation: 11

You ought to be able to use !isNotEmpty(yourVar) to achieve the behavior you want

Upvotes: 0

Matt McCutchen
Matt McCutchen

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

Related Questions