我正在尝试Google Closure,特别是用于强制类型安全的注释性内容。为了测试我做错了什么,尽管编译器不会告诉我这是...

这是代码:

// ==ClosureCompiler==
// @output_file_name default.js
// @compilation_level SIMPLE_OPTIMIZATIONS
// ==/ClosureCompiler==

/**
 * A card.
 * @constructor
 * @param {String} cardName The exact name of the card
 * @param {Kinetic.Layer} layer The layer for the card
 */
function CardObject(cardName, layer)
{
    /** @type {Number} */
    var number = cardName;
}

因此,我有一个变量number,我说它是Number,我尝试为其分配一个字符串。这应该是不可能的,对吧?尽管编译器不会告诉我...

为什么不告诉我那是错的?

最佳答案

Closure Compiler使用warning levels确定在编译过程中启用了哪些检查。三个警告级别是:

  • 安静
  • 默认
  • VERBOSE

  • 例如,使用编译级别SIMPLE_OPTIMIZATIONS,您仍然会收到类型检查警告,并将警告级别设置为VERBOSE

    // ==ClosureCompiler==
    // @output_file_name default.js
    // @compilation_level SIMPLE_OPTIMIZATIONS
    // @warning_level VERBOSE
    // ==/ClosureCompiler==
    
    /**
     * A card.
     * @constructor
     * @param {String} cardName The exact name of the card
     * @param {Kinetic.Layer} layer The layer for the card
     */
    function CardObject(cardName, layer)
    {
        /** @type {Number} */
        var number = cardName;
    }
    

    输出

    Number of warnings: 2
    
    JSC_TYPE_PARSE_ERROR: Bad type annotation. Unknown type Kinetic.Layer at line 5
    character 10
    * @param {Kinetic.Layer} layer The layer for the card
              ^
    JSC_TYPE_MISMATCH: initializing variable
    found   : (String|null|undefined)
    required: (Number|null) at line 10 character 13
    var number = cardName;
                 ^
    

    为了准确了解与每个警告级别相关的检查,这是WarningLevels.java中的相关代码。

    安静的

    /**
     * Silence all non-essential warnings.
     */
    private static void silenceAllWarnings(CompilerOptions options) {
      // Just use a ShowByPath warnings guard, so that we don't have
      // to maintain a separate class of warnings guards for silencing warnings.
      options.addWarningsGuard(
          new ShowByPathWarningsGuard(
              "the_longest_path_that_cannot_be_expressed_as_a_string"));
    
      // Allow passes that aren't going to report anything to be skipped.
    
      options.checkRequires = CheckLevel.OFF;
      options.checkProvides = CheckLevel.OFF;
      options.checkMissingGetCssNameLevel = CheckLevel.OFF;
      options.aggressiveVarCheck = CheckLevel.OFF;
      options.checkTypes = false;
      options.setWarningLevel(DiagnosticGroups.CHECK_TYPES, CheckLevel.OFF);
      options.checkUnreachableCode = CheckLevel.OFF;
      options.checkMissingReturn = CheckLevel.OFF;
      options.setWarningLevel(DiagnosticGroups.ACCESS_CONTROLS, CheckLevel.OFF);
      options.setWarningLevel(DiagnosticGroups.CONST, CheckLevel.OFF);
      options.setWarningLevel(DiagnosticGroups.CONSTANT_PROPERTY, CheckLevel.OFF);
      options.checkGlobalNamesLevel = CheckLevel.OFF;
      options.checkSuspiciousCode = false;
      options.checkGlobalThisLevel = CheckLevel.OFF;
      options.setWarningLevel(DiagnosticGroups.GLOBAL_THIS, CheckLevel.OFF);
      options.setWarningLevel(DiagnosticGroups.ES5_STRICT, CheckLevel.OFF);
      options.checkCaja = false;
    }
    

    默认
    /**
     * Add the default checking pass to the compilation options.
     * @param options The CompilerOptions object to set the options on.
     */
    private static void addDefaultWarnings(CompilerOptions options) {
      options.checkSuspiciousCode = true;
      options.checkUnreachableCode = CheckLevel.WARNING;
      options.checkControlStructures = true;
    }
    

    详细
    /**
     * Add all the check pass that are possibly relevant to a non-googler.
     * @param options The CompilerOptions object to set the options on.
     */
    private static void addVerboseWarnings(CompilerOptions options) {
      addDefaultWarnings(options);
    
      // checkSuspiciousCode needs to be enabled for CheckGlobalThis to get run.
      options.checkSuspiciousCode = true;
      options.checkGlobalThisLevel = CheckLevel.WARNING;
      options.checkSymbols = true;
      options.checkMissingReturn = CheckLevel.WARNING;
    
      // checkTypes has the side-effect of asserting that the
      // correct number of arguments are passed to a function.
      // Because the CodingConvention used with the web service does not provide a
      // way for optional arguments to be specified, these warnings may result in
      // false positives.
      options.checkTypes = true;
      options.checkGlobalNamesLevel = CheckLevel.WARNING;
      options.aggressiveVarCheck = CheckLevel.WARNING;
      options.setWarningLevel(
          DiagnosticGroups.MISSING_PROPERTIES, CheckLevel.WARNING);
      options.setWarningLevel(
          DiagnosticGroups.DEPRECATED, CheckLevel.WARNING);
    }
    

    请注意,options.checkTypes = true;仅设置为VERBOSE警告级别。正如Speransky Danil指出的那样,在使用编译级别ADVANCED_OPTIMIZATIONS时,也会启用类型检查。

    另外,可以使用Closure Compiler应用程序(jar文件)使用编译器标志分别控制警告的类别:
  • --jscomp_off
  • --jscomp_warning
  • --jscomp_error

  • 可以指定的警告类别如下:
  • accessControls
  • ambiguousFunctionDecl
  • checkRegExp
  • checkTypes
  • checkVars
  • const
  • constantProperty
  • 不推荐使用
  • plicateMessage
  • es5严格
  • externs验证
  • fileoverview标签
  • globalThis
  • internetExplorer检查
  • invalidCasts
  • 缺少属性
  • nonStandardJsDocs
  • strictModuleDepCheck
  • 类型无效
  • undefinedNames
  • undefined variable
  • 未知定义
  • uselessCode
  • visibility

  • 例如,可以单独启用类型检查警告:
    --jscomp_warning=checkTypes
    

    关于javascript - Google Closure Annotating不会告诉我我错了,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12236862/

    10-13 01:06