有没有办法动态检查类型的instanceof?

时间:2014-06-05 09:08:08

标签: typescript

以下是伪代码,但我认为最清楚我要做的是:

class C {
    public var x: number = 34;
}

var enforceType<T> = (x: T) : T {
    if (x instanceof T) {
        return x;
    } else {
        console.log(x);
        console.log(T.toString());
        throw ("wrong type!");
    }
}

enforceType<C>({});  // should raise the exception!

问题是T不是类,而是类型,因此instanceof不起作用,toString也不起作用。但有没有办法在运行时检查值是否属于我有编译时的类型?

2 个答案:

答案 0 :(得分:0)

  

但是有没有办法在运行时检查值是否属于我有编译时的类型

没有。

但是

enforceType<C>({});

应该是编译错误!

确实是:

class C {
    public x: number = 34;
}

function enforceType<T>(x: T) : T {
    return x;
}

enforceType<C>({});  // compile error!

答案 1 :(得分:0)

我有一个解决方案,但它非常疯狂。我的想法是首先将“幻像对象”传递给类型检查函数,并且在运行时,enforceType将深入比较每个对象与该幻像:

var enforceType = (phantom: any) => {
    return (x: any) => {
        if (subtypeof(x, phantom)) {
            return x;
        } else {
            console.log("error", x, phantom);
            throw ("wrong type!");
        }
    }
}

var subtypeof = (_sub, _super) => {
    if (typeof _sub !== typeof _super) {
        return false;
    }

    if (typeof(_sub) === "object") {
        if (_sub === null || _super === null) {
            return true;
        }

        for (var x in _super) {
            if (!(x in _sub)) { return false; }
            if (!subtypeof(_sub[x], _super[x])) { return false; }
        }
    }

    return true;
}

class C {
    constructor(public x: number) {
        return;
    }
}

var enforceC = enforceType(new C(0));

console.log(enforceC({x: 8}));         // no exception.  good.
console.log(enforceC({z: "8"}));       // exception.  also good.

这对我的问题基本上是'是'答案,但我不喜欢它有两个原因:

  • 这有点令人费解(但我认为可能有一种方法可以将enforceC实现为(静态)类方法,并通过混合将其提供给任意类;这会稍微改善一些事情。) / p>

  • 它在运行时对每个对象进行深度比较。对于通过ajax进入的对象来说,这可能是微不足道的,但它绝对是要仔细地进行基准测试,或者最好在生产代码中禁用它。