Dynamic Type Checks

Topics: Language Specification
Dec 6, 2013 at 6:10 PM
Edited Dec 6, 2013 at 9:02 PM
Chapter 7.4 states that there is no way to dynamically check if an object implements a given interface. I think the example proposal for how to check the type is incorrect. Given the interface
interface Shaker {
    shake: () => void;
}
the proposed check in the spec is
function asShaker(obj: any): MoverShaker {
    return obj && obj.shake ? obj : null;
}
However, this will yield asShaker({ shake: null }) === null, which imho is incorrect (null is an allowed value, but falsy) and should return the passed object instead. A better (but not sufficient) check is
function asShaker(obj: any): MoverShaker {
    return obj && typeof obj.shake !== "undefined" ? obj : null;
}
In fact, it can be improved even further by actually checking typeof obj.shake === "function".

Maybe the spec should just state that there is no way to actually check the type dynamically in a reliable manner. The following will cause the result to be typed incorrectly even though Typescript is happy (and I don't see a way around it), proving that asFoo is (still) not working correctly:
interface Foo {
    shake: () => boolean;
}

var myObj = {
    shake: function () {
        return 0;
    }
};

function asFoo(obj: any): Foo {
    return obj && typeof obj.shake === "function" ? obj : null;
}

var uhoh: boolean = asFoo(myObj).shake(); // *should* ideally throw NPE
typeof uhoh; // "number"