Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I do instanceof on a union?

It won't allow an instanceof in this case - why?

public assign(color: string | ColorProperty | RgbProperty | RgbColor): void {
    super.assign(color);

    if (color instanceof ColorProperty) {

ps - I LOVE unions!!!

like image 239
David Thielen Avatar asked Jan 30 '26 08:01

David Thielen


2 Answers

It's not quite correct to say that any has to be present in the union. This works as well.

class Foo { } 
class Bar { }

var x: Foo | Bar = new Foo();
if (x instanceof Foo) {
    // this is ok
}

However, this doesn't work, even though there's no union.

var n: number = 123;
if (n instanceof Foo) {
    // compile error
}

The problem is stated in the compiler error.

The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter.

So it seems when a union contains any, you're always allowed to treat the values as if they were any, meaning there are no compile-time restrictions. Otherwise, the compiler only allows operations which are allowed to be applied to any of the individual types.

like image 89
recursive Avatar answered Jan 31 '26 23:01

recursive


It seems that the instanceof keyword must have a type any included in the union in order to use it within a function.
My guess would be that the compiler needs to handle the case where all of your type guards return false - and therefore the type is inferred as any.

function assign(_color: any | string | ColorProperty | RbgProperty) {
    if (_color instanceof ColorProperty) {
    }
    // else may not be a string | ColorProperty | RbgProperty
}
like image 26
blorkfish Avatar answered Feb 01 '26 01:02

blorkfish