JSDoc @type标签的感叹号有什么用?

时间:2018-12-14 06:25:09

标签: javascript visual-studio-code google-closure-compiler jsdoc

VS Code解析以下内容,就好像没有感叹号一样,没有任何错误:

const el = /** @type {HTMLElement!} */ (document.getElementById("abc"));

它有什么作用?官方JSDoc文档说only about preceding marks

  

表示该值是指定类型,但不能为null。

不确定什么标记。

1 个答案:

答案 0 :(得分:3)

const el = /** @type {HTMLElement!} */ (document.getElementById("abc"));

是类型转换。它说document.getElementById("abc")是HTMLElement,而不是null。可能添加了注释是因为getElementById返回HTMLElement或null。

此行的作者应100%确信ID为ABC的元素存在,因为在进行此强制转换后,Closure Compiler会将这种类型视为HTMLElement,而不是可能是HTMLElementnull

用于类型转换的类型遵循与外部类型相同的规则,因此要直接演示使用这些类型,请遵循不使用类型转换。

如OP所述,在Closure Compiler中,感叹号表示类型必须存在,并且不能为null。另外,问号表示它可以是类型,也可以是null

以下面的代码为例:

// ==ClosureCompiler==
// @compilation_level ADVANCED_OPTIMIZATIONS
// @output_file_name default.js
// @formatting pretty_print
// ==/ClosureCompiler==

const body = document.querySelector('body');

const /** @export {Element!} */ n1 = body;
const /** @export {!Element} */ n2 = body;
const /** @export {Element} */ n3 = null;
const /** @export {?Element} */ n4 = null;
const /** @export {Element?} */ n5 = null;

console.log({
  n1,
  n2,
  n3,
  n4,
})

还有run it through the Closure Compiler,这是编译器生成的警告:

JSC_TYPE_MISMATCH: initializing variable
found   : (Element|null)
required: Element at line 3 character 37
const /** @export {Element!} */ n1 = body;
                                     ^
JSC_TYPE_MISMATCH: initializing variable
found   : (Element|null)
required: Element at line 4 character 37
const /** @export {!Element} */ n2 = body;
                                     ^

请注意,bodydocument.querySelector返回,类型为{?Element},我们已经说过,编译器可以将其理解为Element或{{1} },也称为null。此示例说明该符号也可以表示为Element|null?Element