Javascript 在闭包编译器中公开本地类型

Javascript 在闭包编译器中公开本地类型,javascript,scope,google-closure-compiler,Javascript,Scope,Google Closure Compiler,我试图公开函数的返回类型,其中返回类型是在函数自身的范围内定义的 // ==ClosureCompiler== // @compilation_level ADVANCED_OPTIMIZATIONS // ==/ClosureCompiler== /** @return {MyType} */ function func(){ /** @constructor */ function MyType(){} return new MyType(); } /** @type {M

我试图公开函数的返回类型,其中返回类型是在函数自身的范围内定义的

// ==ClosureCompiler==
// @compilation_level ADVANCED_OPTIMIZATIONS
// ==/ClosureCompiler==

/** @return {MyType} */
function func(){
  /** @constructor */
  function MyType(){}

  return new MyType();
}

/** @type {MyType} */
var instance = func();

当我编译它时,我得到两个类型错误,一个是
@return
注释,另一个是
@type
注释。两个错误都表示
未知类型MyType
。有没有办法通过类型检查来编译此模式?

可能它找不到类型,因为创建
实例时,
MyType
作为类型不可用(不能新建MyType()或MyType的实例instanceof)

这可以通过在与instance相同的范围内添加typedef或在与MyType相同的范围内创建instance来解决

两者:

以及:

不会产生任何警告

[更新]

通过注释提供复杂的类型将是非常困难的。您可以根据需要使类型复杂化。使用externs将不起作用,因为externs变量及其函数不会被重命名为较短的名称(没有一些额外的编译参数),并且不能重新定义类型。因此,我猜您基本上一直在提供typedef注释:

/** @typedef {{hands:number,doSomething:function(string):boolean}} */
var MyType;
/** @return {MyType} Returns new MyType **/
function func(){
  /** @constructor */
  function MyType(){
   this.hands=22;
  }
  MyType.prototype.doSomething=function(msg){
    return true;
  }
  return new MyType();
}
/** @type {MyType} */
var instance = func();
/** @type string */
var myString=instance.hands;//warning:found number required string
/** @type Array */
var myArray=instance.doSomething("hi");//found boolean required Array

instance.doSomething(22);//found number required string
instance.doSomething();//at leas 1 argument(s)

问题是“MyType”的作用域为“func”,在外部不可用。您最好在全局范围内定义@接口,并在定义函数之外使用该类型

嗨,HMR,我相信这是它找不到类型的正确原因。第一个解决方案看起来和我想要的很接近,但是它接受函数中对象实例的任何类型,我希望找到一种方法使它只接受MyType的实例。(即,
function func(){return{};}
编译时没有错误,但我希望它有一个类型检查错误)我知道在这个外部作用域中,我不能在运行时执行类似于MyType
实例实例的操作,因为
MyType
不存在于该作用域中。但是我希望它能在编译时被整理出来。@Paulpro我的猜测是,当JS在使用它时找不到类型,那么编译器也找不到,但我不确定编译器是如何做到的。我已经更新了我的答案,并且认为您必须使用
类型
注释来定义它。它可以像你想要的那样复杂,但如果你能把它分散在多行上就好了。我还没有找到一个办法。
function func(){
  /** @constructor */
  function MyType(){
  }
  /** @type {MyType} */
  var instance = new MyType();
  return new MyType();
}
/** @typedef {{hands:number,doSomething:function(string):boolean}} */
var MyType;
/** @return {MyType} Returns new MyType **/
function func(){
  /** @constructor */
  function MyType(){
   this.hands=22;
  }
  MyType.prototype.doSomething=function(msg){
    return true;
  }
  return new MyType();
}
/** @type {MyType} */
var instance = func();
/** @type string */
var myString=instance.hands;//warning:found number required string
/** @type Array */
var myArray=instance.doSomething("hi");//found boolean required Array

instance.doSomething(22);//found number required string
instance.doSomething();//at leas 1 argument(s)