Search code examples
node.jstypescriptcastingreturninstanceof

Typescript: instanceof check doesn't smart cast


I have an event listener callback like so:

function(ev: Event) {
    var userBox = id("user-box");
    var target = ev.target;
    // here
}

Now, I need to cast target to Element. Why does this compile:

function(ev: Event) {
    var userBox = id("user-box");
    var target = ev.target;
    if (target instanceof Element) {
        if (userBox.contains(target)) {
            // do something
        }
    }
}

... but this doesn't?

function(ev: Event) {
    var userBox = id("user-box");
    var target = ev.target;
    if (target !instanceof Element) {
        return;
    }
    if (userBox.contains(target)) {
        // do something
    }
}

Solution

  • variable instanceof XYZ is a single operation that yields a boolean value. It can be inverted by adding parenthesis: !(target instanceof Element). When you do target! instanceof Element, you are invoking the non-null assertion operator in TypeScript on target, which is a compile-time assertion.

    E.g.

    function(ev: Event) {
        var userBox = id("user-box");
        var target = ev.target;
        if (!(target instanceof Element)) {
            return;
        }
        if (userBox.contains(target)) {
            // do something
        }
    }