หมายเหตุ: หน้านี้ไม่ใช่เวอร์ชันล่าสุด รายการทั้งหมดจะได้รับการดูแลที่ https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler
ภาพรวม
Closure Compiler สามารถใช้ข้อมูลประเภทข้อมูลเกี่ยวกับตัวแปร JavaScript เพื่อให้การเพิ่มประสิทธิภาพและคำเตือนที่ดียิ่งขึ้น อย่างไรก็ตาม JavaScript ไม่มีวิธีประกาศประเภท
เนื่องจาก JavaScript ไม่มีไวยากรณ์สำหรับการประกาศประเภทตัวแปร คุณจึงต้องใช้ความคิดเห็นในโค้ดเพื่อระบุประเภทข้อมูล
ภาษาประเภทของ Closure Compiler มาจากคำอธิบายประกอบ ที่ใช้โดย เครื่องมือสร้างเอกสาร JSDoc แม้ว่าต่อมาจะมีความแตกต่างกัน ตอนนี้รวมถึงคำอธิบายประกอบหลายรายการที่ JSDoc ไม่รองรับ และในทางกลับกัน เอกสารนี้อธิบายชุดคำอธิบายประกอบและนิพจน์ประเภทที่ Closure Compiler เข้าใจ
แท็ก JSDoc
Closure Compiler จะค้นหาข้อมูลประเภทในแท็ก JSDoc ใช้แท็ก JSDoc ที่อธิบายไว้ในตารางอ้างอิงด้านล่างเพื่อ ช่วยคอมไพเลอร์เพิ่มประสิทธิภาพโค้ดและตรวจสอบข้อผิดพลาดเกี่ยวกับประเภทที่อาจเกิดขึ้น และข้อผิดพลาดอื่นๆ
ตารางนี้มีเฉพาะแท็กที่มีผลต่อลักษณะการทำงาน ของ Closure Compiler ดูข้อมูลเกี่ยวกับแท็ก JSDoc อื่นๆ ได้ที่ เอกสารประกอบของชุดเครื่องมือ JSDoc
แท็ก | คำอธิบาย |
---|---|
@abstract
|
ทำเครื่องหมายเมธอดเป็นนามธรรม คล้ายกับการตั้งค่าเมธอดเป็น
คอมไพเลอร์จะแสดงคำเตือนหากเมธอดที่ทำเครื่องหมายด้วย /** @abstract */ foo.MyClass.prototype.abstractMethod = function() {}; |
@const
|
ทำเครื่องหมายตัวแปรเป็นแบบอ่านอย่างเดียว คอมไพเลอร์สามารถ
แทรกตัวแปร การประกาศประเภทเป็นแบบไม่บังคับ
คอมไพเลอร์จะแสดงคำเตือนหากมีการกำหนดค่าให้กับตัวแปรที่ทำเครื่องหมายด้วย /** @const */ var MY_BEER = 'stout'; /** * My namespace's favorite kind of beer. * @const {string} */ mynamespace.MY_BEER = 'stout'; /** @const */ MyClass.MY_BEER = 'stout'; |
@constructor
|
ทำเครื่องหมายฟังก์ชันเป็นตัวสร้าง
คอมไพเลอร์ต้องมีคำอธิบายประกอบ เช่น /** * A rectangle. * @constructor */ function GM_Rect() { ... } |
@define
|
ระบุค่าคงที่ที่คอมไพเลอร์แทนที่ได้ในเวลาคอมไพล์
จากตัวอย่างทางด้านซ้าย คุณสามารถส่งแฟล็ก
--define='ENABLE_DEBUG=false'
ไปยังคอมไพเลอร์เพื่อเปลี่ยนค่าของ
ENABLE_DEBUG เป็น false
ค่าคงที่ที่กำหนดอาจเป็นประเภทตัวเลข สตริง หรือบูลีน
อนุญาตให้ใช้ Define ในขอบเขตส่วนกลางเท่านั้น
เช่น /** @define {boolean} */ var ENABLE_DEBUG = true; /** @define {boolean} */ goog.userAgent.ASSUME_IE = false; |
@deprecated
|
ทำเครื่องหมายฟังก์ชัน เมธอด หรือพร็อพเพอร์ตี้เพื่อให้การใช้ฟังก์ชัน เมธอด หรือพร็อพเพอร์ตี้นั้นๆ แสดงคำเตือนของคอมไพเลอร์ที่ระบุว่าไม่ควรใช้ฟังก์ชัน เมธอด หรือพร็อพเพอร์ตี้นั้นอีกต่อไป เช่น /** * Determines whether a node is a field. * @return {boolean} True if the contents of * the element are editable, but the element * itself is not. * @deprecated Use isField(). */ BN_EditUtil.isTopEditableField = function(node) { ... }; |
@dict
|
เช่น /** * @constructor * @dict */ function Foo() {} var obj1 = new Foo(); obj1['x'] = 123; obj1.x = 234; // warning var obj2 = /** @dict */ { 'x': 321 }; obj2.x = 123; // warning |
@enum
|
ระบุประเภทของ Enum Enum คือออบเจ็กต์ที่มีพร็อพเพอร์ตี้
ซึ่งประกอบด้วยชุดค่าคงที่ที่เกี่ยวข้อง แท็ก ป้ายกำกับประเภทของ Enum จะมีผลกับพร็อพเพอร์ตี้แต่ละรายการของ
Enum เช่น หากการแจงนับมีประเภท เช่น /** * Enum for tri-state values. * @enum {number} */ project.TriState = { TRUE: 1, FALSE: -1, MAYBE: 0 }; |
@export
|
เมื่อพิจารณาจากโค้ดนี้ /** @export */ foo.MyPublicClass.prototype.myPublicMethod = function() { // ... };
เมื่อคอมไพเลอร์ทำงานด้วยแฟล็ก goog.exportProperty(foo.MyPublicClass.prototype, 'myPublicMethod', foo.MyPublicClass.prototype.myPublicMethod); ซึ่งจะส่งออกสัญลักษณ์ไปยังโค้ดที่ยังไม่ได้คอมไพล์ คุณสามารถเขียน
/** * @export * @type {SomeType} */ โค้ดที่ใช้คำอธิบายประกอบ
|
@extends
|
ทำเครื่องหมายคลาสหรืออินเทอร์เฟซว่าสืบทอดมาจากคลาสอื่น ชั้นเรียนที่ทำเครื่องหมายด้วย
หมายเหตุ:
ดูตัวอย่างการใช้งานการรับค่าได้ที่
ฟังก์ชัน เช่น /** * Immutable empty node list. * @constructor * @extends {goog.ds.BasicNodeList} */ goog.ds.EmptyNodeList = function() { ... }; |
@final
|
ระบุว่าไม่สามารถขยายเวลาชั้นเรียนนี้ได้ สำหรับเมธอด จะระบุว่าไม่อนุญาตให้คลาสย่อยแทนที่เมธอดนั้น เช่น /** * A class that cannot be extended. * @final * @constructor */ sloth.MyFinalClass = function() { ... } /** * A method that cannot be overridden. * @final */ sloth.MyFinalClass.prototype.method = function() { ... }; |
@implements
|
ใช้กับ
คอมไพเลอร์จะแสดงคำเตือนหากคุณติดแท็กตัวสร้างด้วย เช่น /** * A shape. * @interface */ function Shape() {}; Shape.prototype.draw = function() {}; /** * @constructor * @implements {Shape} */ function Square() {}; Square.prototype.draw = function() { ... }; |
@implicitCast
|
คำอธิบายประกอบนี้จะปรากฏได้เฉพาะในการประกาศพร็อพเพอร์ตี้ภายนอกเท่านั้น
พร็อพเพอร์ตี้มีประเภทที่ประกาศไว้ แต่คุณสามารถกำหนดประเภทใดก็ได้ให้กับพร็อพเพอร์ตี้นั้นโดยไม่มีคำเตือน เมื่อเข้าถึงพร็อพเพอร์ตี้ คุณจะได้รับค่าของประเภทที่ประกาศ เช่น /** * @type {string} * @implicitCast */ Element.prototype.innerHTML; |
@inheritDoc
|
ระบุว่าเมธอดหรือพร็อพเพอร์ตี้ของคลาสย่อย
ซ่อนเมธอดหรือพร็อพเพอร์ตี้ของคลาสแม่โดยเจตนา และมี
เอกสารประกอบที่เหมือนกันทุกประการ โปรดทราบว่า
แท็ก เช่น /** @inheritDoc */ project.SubClass.prototype.toString = function() { ... }; |
@interface
|
ทำเครื่องหมายฟังก์ชันเป็นอินเทอร์เฟซ อินเทอร์เฟซจะระบุสมาชิกที่จำเป็นของประเภท คลาสใดก็ตามที่ใช้การติดตั้งอินเทอร์เฟซ
ต้องใช้เมธอดและพร็อพเพอร์ตี้ทั้งหมดที่กำหนดไว้ใน
ต้นแบบของอินเทอร์เฟซ
ดู
คอมไพเลอร์จะตรวจสอบว่าไม่มีการสร้างอินเทอร์เฟซ หากใช้คีย์เวิร์ด เช่น /** * A shape. * @interface */ function Shape() {}; Shape.prototype.draw = function() {}; /** * A polygon. * @interface * @extends {Shape} */ function Polygon() {}; Polygon.prototype.getSides = function() {}; |
@lends
|
ระบุว่าควร ถือว่าคีย์ของออบเจ็กต์ลิเทอรัลเป็นพร็อพเพอร์ตี้ของออบเจ็กต์อื่น คำอธิบายประกอบนี้ ควรปรากฏในออบเจ็กต์ลิเทอรัลเท่านั้น
โปรดทราบว่าชื่อในวงเล็บปีกกาไม่ใช่ชื่อประเภทเหมือน
ในคำอธิบายประกอบอื่นๆ ซึ่งเป็นชื่อออบเจ็กต์ โดยจะตั้งชื่อ
ออบเจ็กต์ที่ยืมพร็อพเพอร์ตี้
เช่น เอกสารประกอบของชุดเครื่องมือ JSDocมีข้อมูลเพิ่มเติมเกี่ยวกับการอธิบายประกอบนี้ เช่น goog.object.extend( Button.prototype, /** @lends {Button.prototype} */ ({ isButton: function() { return true; } })); |
@license หรือ @preserve
|
บอกคอมไพเลอร์ให้แทรกความคิดเห็นที่เชื่อมโยง ก่อนโค้ดที่คอมไพล์สำหรับไฟล์ที่ทำเครื่องหมาย คำอธิบายประกอบนี้ช่วยให้ประกาศสำคัญ (เช่น ใบอนุญาตทางกฎหมายหรือข้อความลิขสิทธิ์) ยังคงอยู่หลังการคอมไพล์โดยไม่มีการเปลี่ยนแปลง ระบบจะเก็บตัวแบ่งบรรทัดไว้ เช่น /** * @preserve Copyright 2009 SomeThirdParty. * Here is the full license text and copyright * notice for this file. Note that the notice can span several * lines and is only terminated by the closing star and slash: */ |
@nocollapse
|
ระบุพร็อพเพอร์ตี้ที่คอมไพเลอร์ไม่ควรยุบเป็น
ตัวแปร เช่น /** * A namespace. * @const */ var foo = {}; /** * @nocollapse */ foo.bar = 42; window['foobar'] = foo.bar; |
@nosideeffects
|
ระบุว่าการเรียกฟังก์ชันภายนอกที่ประกาศไว้ไม่มีผลข้างเคียง
คำอธิบายประกอบนี้ช่วยให้คอมไพเลอร์นำการเรียกฟังก์ชันออกได้
หากไม่ได้ใช้ค่าที่ส่งคืน โดยจะอนุญาตให้ใช้คำอธิบายประกอบใน
เช่น /** @nosideeffects */ function noSideEffectsFn1() {} /** @nosideeffects */ var noSideEffectsFn2 = function() {}; /** @nosideeffects */ a.prototype.noSideEffectsFn3 = function() {}; |
@override
|
ระบุว่าเมธอดหรือพร็อพเพอร์ตี้ของคลาสย่อยซ่อนเมธอดหรือพร็อพเพอร์ตี้ของคลาสแม่โดยเจตนา หากไม่มีคำอธิบายประกอบอื่นๆ รวมอยู่ด้วย เมธอดหรือพร็อพเพอร์ตี้จะรับช่วงคำอธิบายประกอบ จากคลาสแม่โดยอัตโนมัติ เช่น /** * @return {string} Human-readable representation of * project.SubClass. * @override */ project.SubClass.prototype.toString = function() { ... }; |
@package
|
ทำเครื่องหมายสมาชิกหรือพร็อพเพอร์ตี้เป็นแบบแพ็กเกจส่วนตัว เฉพาะโค้ดในไดเรกทอรีเดียวกัน
เท่านั้นที่จะเข้าถึงชื่อที่ทำเครื่องหมาย
ตัวสร้างสาธารณะอาจมี เช่น /** * Returns the window object the foreign document resides in. * * @return {Object} The window object of the peer. * @package */ goog.net.xpc.CrossPageChannel.prototype.getPeerWindowObject = function() { // ... }; |
@param
|
ใช้กับคำจำกัดความของเมธอด ฟังก์ชัน และตัวสร้างเพื่อระบุ
ประเภทของอาร์กิวเมนต์ฟังก์ชัน แท็ก
แท็ก
หรือจะใส่คำอธิบายประกอบประเภทพารามิเตอร์แบบอินไลน์ก็ได้
(ดูฟังก์ชัน เช่น /** * Queries a Baz for items. * @param {number} groupNum Subgroup id to query. * @param {string|number|null} term An itemName, * or itemId, or null to search everything. */ goog.Baz.prototype.query = function(groupNum, term) { ... }; function foo(/** number */ a, /** number */ b) { return a - b + 1; } /** * @param {{name: string, age: number}} person */ function logPerson({name, age}) { console.log(`${name} is ${age} years old`); } |
@private
|
ทำเครื่องหมายสมาชิกเป็นส่วนตัว เฉพาะโค้ดในไฟล์เดียวกันเท่านั้นที่จะเข้าถึง
ตัวแปรและฟังก์ชันส่วนกลาง
ที่ทำเครื่องหมาย
นอกจากนี้ คุณยังเข้าถึงพร็อพเพอร์ตี้แบบคงที่สาธารณะของตัวสร้างที่ทำเครื่องหมาย เช่น /** * Handlers that are listening to this logger. * @private {Array<Function>} */ this.handlers_ = []; |
@protected
|
ระบุว่าสมาชิกหรือพร็อพเพอร์ตี้ได้รับการปกป้อง
พร็อพเพอร์ตี้ที่ทำเครื่องหมาย
เช่น /** * Sets the component's root element to the given element. * Considered protected and final. * @param {Element} element Root element for the component. * @protected */ goog.ui.Component.prototype.setElementInternal = function(element) { // ... }; |
@record
|
ทําเครื่องหมายฟังก์ชันเป็นอินเทอร์เฟซเชิงโครงสร้าง อินเทอร์เฟซเชิงโครงสร้าง
คล้ายกับ เช่น /** * Anything with a draw() method. * @record */ function Drawable() {}; Drawable.prototype.draw = function() {}; /** * A polygon. * @param {!Drawable} x */ function render(x) { x.draw(); }; var o = { draw() { /* ... */ } }; render(o); |
@return
|
ระบุประเภทการคืนค่าของคำจำกัดความของเมธอดและฟังก์ชัน
แท็ก
หรือจะใส่คำอธิบายประกอบประเภทการคืนค่าในบรรทัดก็ได้
(ดูฟังก์ชัน
หากฟังก์ชันที่ไม่ได้อยู่ในไฟล์ภายนอกไม่มีค่าที่ส่งคืน คุณสามารถละเว้นแท็ก
เช่น /** * Returns the ID of the last item. * @return {string} The hex ID. */ goog.Baz.prototype.getLastId = function() { ... return id; }; function /** number */ foo(x) { return x - 1; } |
@struct
|
เช่น /** * @constructor * @struct */ function Foo(x) { this.x = x; } var obj1 = new Foo(123); var someVar = obj1.x; // OK obj1.x = "qwerty"; // OK obj1['x'] = "asdf"; // warning obj1.y = 5; // warning var obj2 = /** @struct */ { x: 321 }; obj2['x'] = 123; // warning |
@template
|
เช่น /** * @param {T} t * @constructor * @template T */ Container = function(t) { ... }; |
@this
|
ระบุประเภทของออบเจ็กต์ที่คีย์เวิร์ด
หากต้องการป้องกันคำเตือนของคอมไพเลอร์ คุณต้องใช้
คำอธิบายประกอบ เช่น chat.RosterWidget.extern('getRosterElement', /** * Returns the roster widget element. * @this {Widget} * @return {Element} */ function() { return this.getComponent().getElement(); }); |
@throws
|
ใช้เพื่อบันทึกข้อยกเว้นที่ฟังก์ชันส่งคืน ปัจจุบันเครื่องมือตรวจสอบประเภทไม่ได้ใช้ข้อมูลนี้ โดยจะใช้เพื่อพิจารณาว่าฟังก์ชันที่ประกาศในไฟล์ภายนอกมี ผลข้างเคียงหรือไม่ เช่น /** * @throws {DOMException} */ DOMApplicationCache.prototype.swapCache = function() { ... }; |
@type
|
ระบุประเภทของตัวแปร พร็อพเพอร์ตี้ หรือนิพจน์ แท็ก เมื่อประกาศตัวแปรหรือพารามิเตอร์ฟังก์ชัน
คุณสามารถเขียนคำอธิบายประกอบประเภทแบบอินไลน์โดยละเว้น
เช่น /** * The message hex ID. * @type {string} */ var hexId = hexId; var /** string */ name = 'Jamie'; function useSomething(/** (string|number|!Object) */ something) { ... } |
@typedef
|
ประกาศชื่อแทนสำหรับประเภทที่ซับซ้อนกว่า ปัจจุบันสามารถกำหนด typedef ได้ที่ระดับบนสุดเท่านั้น ไม่ใช่ภายในฟังก์ชัน เราได้แก้ไขข้อจำกัดนี้ใน การอนุมานประเภทใหม่แล้ว เช่น /** @typedef {(string|number)} */ goog.NumberLike; /** @param {goog.NumberLike} x A number or a string. */ goog.readNumber = function(x) { ... } |
@unrestricted
|
ระบุว่าคลาสไม่ใช่ประเภท เช่น /** * @constructor * @unrestricted */ function Foo(x) { this.x = x; } var obj1 = new Foo(123); var someVar = obj1.x; // OK obj1.x = "qwerty"; // OK obj1['x'] = "asdf"; // OK obj1.y = 5; // OK |
นิพจน์ประเภท
คุณระบุประเภทข้อมูลของตัวแปร พร็อพเพอร์ตี้ นิพจน์ หรือพารามิเตอร์ฟังก์ชันได้ด้วยนิพจน์ประเภท นิพจน์ประเภท ประกอบด้วยวงเล็บปีกกา ("{ }") ที่มีชุดค่าผสม ของโอเปอเรเตอร์ประเภทที่อธิบายไว้ด้านล่าง
ใช้การแสดงประเภทกับแท็ก @param
เพื่อประกาศประเภทของพารามิเตอร์ฟังก์ชัน ใช้นิพจน์ประเภทที่มีแท็ก @type
เพื่อประกาศประเภทของตัวแปร พร็อพเพอร์ตี้ หรือนิพจน์
ยิ่งระบุประเภทในโค้ดมากเท่าไหร่ คอมไพเลอร์ก็จะเพิ่มประสิทธิภาพได้มากขึ้นและตรวจพบข้อผิดพลาดได้มากขึ้น
คอมไพเลอร์ใช้คำอธิบายประกอบเหล่านี้เพื่อตรวจสอบประเภทโปรแกรมของคุณ
โปรดทราบว่า Closure Compiler ไม่รับประกันว่าจะสามารถระบุประเภทของทุกนิพจน์ในโปรแกรมของคุณได้ โดยจะพยายามอย่างเต็มที่ด้วยการดูวิธีใช้ตัวแปร
และดูคำอธิบายประกอบประเภทที่แนบมากับการประกาศ
ของตัวแปร จากนั้นจะใช้อัลกอริทึมการอนุมานประเภทหลายรายการเพื่อ
พิจารณาประเภทของนิพจน์ให้ได้มากที่สุด อัลกอริทึมบางส่วนเหล่านี้เป็นแบบตรงไปตรงมา ("หาก x เป็นตัวเลขและเราเห็น y = x;
แสดงว่า y เป็นตัวเลข") บางอย่างก็ซับซ้อนกว่า ("หากพารามิเตอร์แรกของ f's
ระบุไว้เป็นโค้ดเรียกกลับที่ต้องใช้ตัวเลข
และเราเห็น f(function(x) { /** ... */ });
แสดงว่า x ต้องเป็น
ตัวเลข")
ชื่อผู้ให้บริการ | ตัวอย่างไวยากรณ์ | คำอธิบาย |
---|---|---|
ชื่อประเภท |
{boolean} {Window} {goog.ui.Menu}
|
ระบุชื่อของประเภท |
พิมพ์ใบสมัคร |
{Array<string>} อาร์เรย์ของสตริง
|
กำหนดพารามิเตอร์ประเภทด้วยชุดอาร์กิวเมนต์ประเภท คล้ายกับ Generics ของ Java |
Type Union |
{(number|boolean)} ตัวเลขหรือบูลีน โปรดสังเกตวงเล็บ ซึ่งเป็นสิ่งจำเป็น |
ระบุว่าค่าอาจมีประเภท A หรือประเภท B |
ประเภทระเบียน |
{{myNum: number, myObject}}
ประเภทที่ไม่ระบุชื่อที่มีทั้งพร็อพเพอร์ตี้ชื่อ myNum
ซึ่งมีค่าประเภท number และพร็อพเพอร์ตี้
ชื่อ myObject ซึ่งมีค่าประเภทใดก็ได้
|
ระบุว่าค่ามีสมาชิกที่ระบุ ซึ่งมีค่าเป็นประเภทที่ระบุ วงเล็บปีกกาเป็นส่วนหนึ่งของไวยากรณ์ประเภท เช่น หากต้องการ
ระบุ |
ประเภทที่เว้นว่างได้ |
{?number} ตัวเลขหรือ null
|
ระบุว่าค่าเป็นประเภท A หรือ โดยค่าเริ่มต้น ออบเจ็กต์ทุกประเภทจะกำหนดให้เป็น Null ได้ ไม่ว่าจะประกาศด้วยตัวดำเนินการ Nullable หรือไม่ก็ตาม ประเภทออบเจ็กต์กำหนดเป็น สิ่งใดก็ตามยกเว้นฟังก์ชัน สตริง ตัวเลข หรือบูลีน หากต้องการทำให้ประเภทออบเจ็กต์ ไม่เป็นค่าว่าง ให้ใช้ตัวดำเนินการไม่เป็นค่าว่าง |
ประเภทที่ต้องระบุ |
{!Object} ออบเจ็กต์ แต่ไม่ใช่ค่า null
|
ระบุว่าค่าเป็นประเภท A และไม่ใช่ค่าว่าง ฟังก์ชันและค่าทุกประเภท (บูลีน ตัวเลข และสตริง) จะเว้นว่างไม่ได้โดยค่าเริ่มต้น ไม่ว่าจะประกาศด้วยตัวดำเนินการเว้นว่างไม่ได้หรือไม่ก็ตาม หากต้องการทำให้ค่าหรือประเภทฟังก์ชันเป็น Null ได้ ให้ใช้โอเปอเรเตอร์ Nullable |
ประเภทฟังก์ชัน |
{function(string, boolean)} ฟังก์ชันที่ใช้พารามิเตอร์ 2 รายการ (สตริงและบูลีน) และมีค่าส่งคืนที่ไม่รู้จัก |
ระบุฟังก์ชันและประเภทของพารามิเตอร์ของฟังก์ชัน |
ประเภทการแสดงผลของฟังก์ชัน |
{function(): number} ฟังก์ชันที่ไม่รับพารามิเตอร์และแสดงผลตัวเลข |
ระบุประเภทค่าที่ฟังก์ชันแสดงผล |
ประเภทฟังก์ชัน this |
{function(this:goog.ui.Menu, string)} ฟังก์ชันที่รับพารามิเตอร์ 1 รายการ (สตริง) และเรียกใช้ ในบริบทของ goog.ui.Menu |
ระบุประเภทของค่าของ this ภายใน
ฟังก์ชัน |
ประเภทฟังก์ชัน new |
{function(new:goog.ui.Menu, string)} ฟังก์ชันที่ใช้พารามิเตอร์ 1 รายการ (สตริง) และสร้างอินสแตนซ์ใหม่ของ goog.ui.Menu เมื่อเรียกใช้ด้วยคีย์เวิร์ด "new" |
ระบุประเภทที่สร้างขึ้นของตัวสร้าง |
พารามิเตอร์ตัวแปร |
{function(string, ...number): number} ฟังก์ชันที่ใช้พารามิเตอร์ 1 รายการ (สตริง) และพารามิเตอร์จำนวนตัวแปร ที่ต้องเป็นตัวเลข |
ระบุว่าประเภทฟังก์ชันใช้พารามิเตอร์จำนวนตัวแปร และระบุประเภทสำหรับพารามิเตอร์ตัวแปร |
พารามิเตอร์ตัวแปร (ในคำอธิบายประกอบ @param )
|
@param {...number} var_args พารามิเตอร์จำนวนตัวแปรไปยังฟังก์ชันที่มีคำอธิบายประกอบ |
ระบุว่าฟังก์ชันที่มีคำอธิบายประกอบยอมรับพารามิเตอร์จำนวนตัวแปร และระบุประเภทสำหรับพารามิเตอร์ตัวแปร |
พารามิเตอร์ที่ไม่บังคับในคำอธิบายประกอบ @param
|
@param {number=} opt_argument พารามิเตอร์ที่ไม่บังคับของประเภท number
|
ระบุว่าอาร์กิวเมนต์ที่อธิบายโดย
คำอธิบายประกอบ
หากการเรียกเมธอดละเว้นพารามิเตอร์ที่ไม่บังคับ อาร์กิวเมนต์นั้นจะมีค่าเป็น /** * Some class, initialized with an optional value. * @param {Object=} opt_value Some value (optional). * @constructor */ function MyClass(opt_value) { /** * Some value. * @type {Object|undefined} */ this.myValue = opt_value; } |
อาร์กิวเมนต์ที่ไม่บังคับในประเภทฟังก์ชัน |
{function(?string=, number=)} ฟังก์ชันที่รับสตริงที่เลือกได้ซึ่งอนุญาตให้เป็นค่าว่าง 1 รายการและตัวเลขที่เลือกได้ 1 รายการเป็น อาร์กิวเมนต์ |
ระบุว่าอาร์กิวเมนต์ในประเภทฟังก์ชันเป็นแบบไม่บังคับ คุณจะละเว้นอาร์กิวเมนต์ที่ไม่บังคับจากการเรียกฟังก์ชันได้ อาร์กิวเมนต์ที่ไม่บังคับต้องอยู่หลังอาร์กิวเมนต์ที่บังคับในรายการอาร์กิวเมนต์ |
ประเภท ALL | {*} |
ระบุว่าตัวแปรสามารถใช้ประเภทใดก็ได้ |
ประเภท UNKNOWN | {?} |
ระบุว่าตัวแปรสามารถใช้ได้กับทุกประเภท และคอมไพเลอร์ ไม่ควรตรวจสอบประเภทการใช้งานใดๆ ของตัวแปร |
การแคสต์ประเภท
หากต้องการส่งค่าไปยังประเภทที่เฉพาะเจาะจง ให้ใช้ไวยากรณ์นี้
/** @type {!MyType} */ (valueExpression)
ประเภททั่วไป
Closure Compiler รองรับประเภท ฟังก์ชัน และเมธอดทั่วไปเช่นเดียวกับ Java Generics ทำงานกับออบเจ็กต์ประเภทต่างๆ ขณะที่ยังคงรักษาความปลอดภัยของประเภทในเวลาคอมไพล์
คุณสามารถใช้ Generics เพื่อใช้คอลเล็กชันทั่วไปที่เก็บการอ้างอิง ไปยังออบเจ็กต์ประเภทใดประเภทหนึ่ง และอัลกอริทึมทั่วไปที่ทำงานกับ ออบเจ็กต์ประเภทใดประเภทหนึ่ง
การประกาศประเภททั่วไป
คุณทำให้ประเภทเป็นแบบทั่วไปได้โดยการเพิ่ม@template
คำอธิบายประกอบ
ลงในตัวสร้างของประเภท (สำหรับคลาส) หรือการประกาศอินเทอร์เฟซ (สำหรับ
อินเทอร์เฟซ) เช่น
/** * @constructor * @template T */ Foo = function() { ... };
คำอธิบายประกอบ @template T
แสดงว่า Foo
เป็นประเภททั่วไปที่มีเทมเพลตประเภทเดียวคือ T
คุณใช้ประเภทเทมเพลต T
เป็นประเภทภายในขอบเขต
ของคำจำกัดความของ Foo
ได้ เช่น
/** @return {T} */ Foo.prototype.get = function() { ... }; /** @param {T} t */ Foo.prototype.set = function(t) { ... };
เมธอด get
จะแสดงผลออบเจ็กต์ประเภท T
และเมธอด set
จะยอมรับเฉพาะออบเจ็กต์ประเภท T
การสร้างอินสแตนซ์ของประเภททั่วไป
การใช้ตัวอย่างด้านบนซ้ำ คุณจะสร้างอินสแตนซ์ที่ใช้เทมเพลตของ Foo
ได้หลายวิธี ดังนี้
/** @type {!Foo<string>} */ var foo = new Foo(); var foo = /** @type {!Foo<string>} */ (new Foo());
ทั้ง 2 คำสั่งตัวสร้างข้างต้นจะสร้างFoo
อินสแตนซ์
ที่มีประเภทเทมเพลต T
เป็น string
คอมไพเลอร์จะบังคับให้การเรียกใช้เมธอดของ foo
และการเข้าถึงพร็อพเพอร์ตี้ของ foo
เป็นไปตามประเภทที่สร้างจากเทมเพลต เช่น
foo.set("hello"); // OK. foo.set(3); // Error - expected a string, found a number. var x = foo.get(); // x is a string.
นอกจากนี้ คุณยังพิมพ์อินสแตนซ์โดยอาร์กิวเมนต์ของตัวสร้างได้ด้วย
ลองพิจารณาประเภททั่วไปอื่น Bar
/** * @param {T} t * @constructor * @template T */ Bar = function(t) { ... }; var bar = new Bar("hello"); // bar is a Bar<string>
ระบบจะอนุมานประเภทของอาร์กิวเมนต์ไปยังตัวสร้าง Bar
เป็น string
และด้วยเหตุนี้ ระบบจึงอนุมานอินสแตนซ์ที่สร้างขึ้น bar
เป็น Bar<string>
เทมเพลตหลายประเภท
โดยทั่วไปแล้ว เทมเพลตจะมีได้หลายประเภท คลาสแผนที่ต่อไปนี้มีเทมเพลต 2 ประเภท
/** * @constructor * @template Key, Val */ MyMap = function() { ... };
ต้องระบุเทมเพลตทุกประเภทสำหรับประเภททั่วไปในคำอธิบายประกอบ @template
เดียวกันเป็นรายการที่คั่นด้วยคอมมา ลำดับของชื่อประเภทเทมเพลตมีความสำคัญ เนื่องจากคำอธิบายประกอบประเภทเทมเพลตจะใช้ลำดับเพื่อจับคู่ประเภทเทมเพลตกับค่า เช่น
/** @type {MyMap<string, number>} */ var map; // Key = string, Val = number.
ความไม่แปรผันของประเภททั่วไป
Closure Compiler บังคับใช้การพิมพ์ทั่วไปที่ไม่เปลี่ยนแปลง ซึ่งหมายความว่าหากบริบทคาดหวังประเภท Foo<X>
คุณจะส่งประเภท Foo<Y>
ไม่ได้เมื่อ X
และ Y
เป็นประเภทที่แตกต่างกัน แม้ว่าประเภทหนึ่งจะเป็นประเภทย่อยของอีกประเภทหนึ่งก็ตาม เช่น
/** * @constructor */ X = function() { ... }; /** * @extends {X} * @constructor */ Y = function() { ... }; /** @type {Foo<X>} */ var fooX; /** @type {Foo<Y>} */ var fooY; fooX = fooY; // Error fooY = fooX; // Error /** @param {Foo<Y>} fooY */ takesFooY = function(fooY) { ... }; takesFooY(fooY); // OK. takesFooY(fooX); // Error
การสืบทอดประเภททั่วไป
ประเภททั่วไปสามารถรับค่าได้ และประเภทเทมเพลตของประเภททั่วไปอาจเป็นแบบคงที่หรือส่งต่อให้กับประเภทที่รับค่า ตัวอย่าง ของประเภทที่รับค่าซึ่งแก้ไขประเภทเทมเพลตของประเภทซูเปอร์ไทป์มีดังนี้
/** * @constructor * @template T */ A = function() { ... }; /** @param {T} t */ A.prototype.method = function(t) { ... }; /** * @constructor * @extends {A<string>} */ B = function() { ... };
เมื่อขยาย A<string>
แล้ว B
จะมีเมธอด
method
ซึ่งใช้พารามิเตอร์ประเภท string
ต่อไปนี้เป็นตัวอย่างของประเภทการรับค่าที่เผยแพร่ประเภทเทมเพลต ของประเภทซูเปอร์ไทป์
/** * @constructor * @template U * @extends {A<U>} */ C = function() { ... };
เมื่อขยาย A<U>
อินสแตนซ์ที่สร้างจากเทมเพลตของ C
จะมีเมธอด method
ที่ใช้พารามิเตอร์ของเทมเพลต
ประเภท U
คุณสามารถใช้และขยายอินเทอร์เฟซในลักษณะที่คล้ายกันได้ แต่ ประเภทเดียวจะใช้ อินเทอร์เฟซเดียวกันหลายครั้งกับเทมเพลตประเภทต่างๆ ไม่ได้ เช่น
/** * @interface * @template T */ Foo = function() {}; /** @return {T} */ Foo.prototype.get = function() {}; /** * @constructor * @implements {Foo<string>} * @implements {Foo<number>} */ FooImpl = function() { ... }; // Error - implements the same interface twice
ฟังก์ชันและเมธอดทั่วไป
ฟังก์ชันและเมธอดสามารถทำให้เป็นแบบทั่วไปได้โดยการเพิ่ม
คำอธิบายประกอบ @template
ลงในคำจำกัดความของฟังก์ชันและเมธอดนั้นๆ เช่นเดียวกับประเภททั่วไป เช่น
/** * @param {T} a * @return {T} * @template T */ identity = function(a) { return a; }; /** @type {string} */ var msg = identity("hello") + identity("world"); // OK /** @type {number} */ var sum = identity(2) + identity(2); // OK /** @type {number} */ var sum = identity(2) + identity("2"); // Type mismatch