以下是伪代码,但我认为最清楚我要做的是:
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也不起作用。但有没有办法在运行时检查值是否属于我有编译时的类型?
答案 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进入的对象来说,这可能是微不足道的,但它绝对是要仔细地进行基准测试,或者最好在生产代码中禁用它。