最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - What does a proceeding exclamation mark do for JSDoc @type tag? - Stack Overflow

programmeradmin4浏览0评论

VS Code parses the following as if there were no exclamation mark, without any errors:

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

What does it do? The official JSDoc documentation says only about preceding marks:

Indicates that the value is of the specified type, but cannot be null.

Not sure what proceeding marks do.

VS Code parses the following as if there were no exclamation mark, without any errors:

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

What does it do? The official JSDoc documentation says only about preceding marks:

Indicates that the value is of the specified type, but cannot be null.

Not sure what proceeding marks do.

Share Improve this question edited Dec 14, 2018 at 17:08 Graham P Heath 7,4443 gold badges33 silver badges47 bronze badges asked Dec 14, 2018 at 6:25 Kagami Sascha RosylightKagami Sascha Rosylight 1,4922 gold badges16 silver badges31 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 8

TLDR: !HTMLElement and HTMLElement! are the same annotation, practically speaking.


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

Is a type cast. It says that document.getElementById("abc") is an HTMLElement, and not null. The annotation was likely added because getElementById returns either an HTMLElement or null.

The author of this line should be 100% confident that an element with an id of abc exists, because after this cast is made, the Closure Compiler will treat this type as an HTMLElement, instead of possibly an HTMLElement or null.

Types used in casting follow the same rules as types outside of casting, so to demonstrate using these types directly, the examples that follow do not use casting.

As OP says, in Closure Compiler the exclamation mark means the type must exist, and cannot be null. Additionally, a question mark means it could be the type or it could be null.

Take for example the following code:

// ==ClosureCompiler==
// @pilation_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,
})

And run it through the Closure Compiler, here are the warnings the piler generates:

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;
                                     ^

Note that body is returned by document.querySelector with a type of {?Element} , which we've said the piler understands can be either an Element or null, a.k.a. Element|null. This example shows that the notation can also be expressed as ?Element or Element?.

发布评论

评论列表(0)

  1. 暂无评论