Javascript 使用闭包编译器创建结果类型

Javascript 使用闭包编译器创建结果类型,javascript,error-handling,google-closure-compiler,Javascript,Error Handling,Google Closure Compiler,我使用的是闭包编译器,我希望有一个类似生锈的Result类型,它要么包含某个类型的值,要么不包含值和错误,以表示函数的返回值 以下是我的意思的一个例子: /** * @param {function(Result<Element>)} callback */ function bar (callback) { if (...) { var elem = ...; callback(Result.ok(elem)); }

我使用的是闭包编译器,我希望有一个类似生锈的
Result
类型,它要么包含某个类型的值,要么不包含值和错误,以表示函数的返回值

以下是我的意思的一个例子:

/**
 * @param {function(Result<Element>)} callback
*/
function bar (callback) {        
    if (...) {
        var elem = ...;
        callback(Result.ok(elem));
    } else {
        callback(Result.err(new Error("...")));
    }
}

bar(function (result) {
    if (result.ok) {
        // guaranteed to be a non-error result here - no warning
        console.log(result.val.nodeType);
    } else {
        // closure should produce a warning here about undefined prop
        console.log(result.val.nodeType);
    }
});
/**
*@param{function(Result)}回调
*/
函数栏(回调){
如果(…){
var-elem=。。。;
回调(Result.ok(elem));
}否则{
回调(Result.err(新错误(“…”));
}
}
条形图(功能(结果){
if(result.ok){
//此处保证为非错误结果-无警告
console.log(result.val.nodeType);
}否则{
//闭包应该在这里产生一个关于未定义属性的警告
console.log(result.val.nodeType);
}
});
可能的实现(但不会引发警告):

/**
*@constructor
*@T模板
*@param{boolean}好的
*@param{T}val
*@param{Error}err
**/
功能结果(正常、无效、错误){
this.ok=ok;
this.val=val;
this.err=err;
}
/**
*@T模板
*@param{T=}val
*@return{OkResult}
**/
Result.ok=函数(val){
返回新的OkResult(val);
};
/**
*@param{Error}err
*@param{Error=}previous
*@return{ErrResult}
**/
Result.err=函数(err,上一个){
err['previous']=previous;
返回新的ErrResult(err);
};
/**
*@constructor
*@extends{Result}
*@T模板
*@param{T}val
**/
函数OkResult(val){
this.ok=true;
this.val=val;
this.err=null;
}
/**
*@constructor
*@extends{Result}
*@param{Error}err
**/
函数ErrResult(err){
this.ok=false;
this.val=null;
this.err=err;
}
我尝试用一个
Result
超类和两个
OkResult
ErrResult
子类来实现这一点,但是当我尝试编写应该产生警告的代码时,我没有得到任何警告


是否有某种方法可以创建具有上述指定属性的
结果
类型?当试图访问一个错误结果时,它会安全地发出警告,就像它是一个正常的结果一样?

使用经典继承肯定是实现这一点的方法。与其测试
obj.ok
属性,不如检查
instanceof

bar(function (result) {
  if (result instanceof OkResult) {
    // instanceof tests are recognized by the compiler
    // and automatically tightens the types.
    console.log(result.val.nodeType);
  } else if (result instanceof ErrorResult) {
    // closure produces a warning here about undefined prop
    console.log(result.val.nodeType);
  }
});
此外,编译器仅在属性不存在时警告缺少的属性。为了使其为真,不得在任何父类上定义该属性


谢谢你,查德!另外,我将
if(result instanceof ErrorResult)
去掉,并将主体更改为
console.log(result.err)
,它仍然编译,但执行
result.blah会发出警告(我希望如此)。这是否意味着它实际上是在确定只有两种类型的
结果
可能是
OkResult
ErrorResult
,并进行消除过程以确定它是
ErrorResult
?如果是这样,哇,那太棒了。不幸的是没有。这意味着它可以是任何一种类型。啊,这更有意义。如果闭包的分析达到了这样的水平,那将是令人惊讶的。谢谢你的帮助。
bar(function (result) {
  if (result instanceof OkResult) {
    // instanceof tests are recognized by the compiler
    // and automatically tightens the types.
    console.log(result.val.nodeType);
  } else if (result instanceof ErrorResult) {
    // closure produces a warning here about undefined prop
    console.log(result.val.nodeType);
  }
});