ध्यान दें: यह पेज पुराना हो चुका है. पूरी सूची यहां दी गई है: https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler
खास जानकारी
Closure Compiler, JavaScript वैरिएबल के डेटा टाइप की जानकारी का इस्तेमाल कर सकता है. इससे बेहतर ऑप्टिमाइज़ेशन और चेतावनियां मिल सकती हैं. JavaScript में, टाइप तय करने का कोई तरीका नहीं है.
JavaScript में किसी वैरिएबल के टाइप का एलान करने के लिए कोई सिंटैक्स नहीं होता. इसलिए, आपको कोड में टिप्पणियों का इस्तेमाल करके डेटा टाइप के बारे में बताना होगा.
Closure Compiler की टाइप लैंग्वेज, JSDoc दस्तावेज़ जनरेट करने वाले टूल के इस्तेमाल किए गए एनोटेशन से ली गई है. हालांकि, अब यह अलग हो गई है. अब इसमें कई ऐसे एनोटेशन शामिल हैं जिन्हें JSDoc इस्तेमाल नहीं करता. इसके उलट, JSDoc में ऐसे कई एनोटेशन शामिल हैं जिन्हें यह इस्तेमाल नहीं करता. इस दस्तावेज़ में, एनोटेशन और टाइप एक्सप्रेशन के उस सेट के बारे में बताया गया है जिसे Closure Compiler समझता है.
JSDoc टैग
Closure Compiler, JSDoc टैग में टाइप की जानकारी ढूंढता है. नीचे दी गई रेफ़रंस टेबल में बताए गए JSDoc टैग का इस्तेमाल करें. इससे कंपाइलर को आपके कोड को ऑप्टिमाइज़ करने में मदद मिलेगी. साथ ही, वह टाइप से जुड़ी संभावित गड़बड़ियों और अन्य गलतियों की जांच कर पाएगा.
इस टेबल में सिर्फ़ ऐसे टैग शामिल हैं जो Closure Compiler के व्यवहार पर असर डालते हैं. अन्य JSDoc टैग के बारे में जानकारी के लिए, JSDoc Toolkit का दस्तावेज़ देखें.
टैग | ब्यौरा |
---|---|
@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 {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
|
इस एनोटेशन का इस्तेमाल, किसी क्लास या इंटरफ़ेस को दूसरी क्लास से इनहेरिट करने के लिए किया जाता है.
ध्यान दें:
इनहेरिटेंस को लागू करने के उदाहरण के लिए, Closure Library फ़ंक्शन उदाहरण के लिए: /** * 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
|
यह एनोटेशन सिर्फ़ externs प्रॉपर्टी के एलान में दिख सकता है.
प्रॉपर्टी का टाइप तय किया गया है, लेकिन आपको चेतावनी मिले बिना ही इसे कोई भी टाइप असाइन करने का विकल्प मिलता है. प्रॉपर्टी को ऐक्सेस करने पर, आपको तय किए गए टाइप की वैल्यू वापस मिलती है. उदाहरण के लिए,
/** * @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
|
यह तरीके और फ़ंक्शन की परिभाषाओं के रिटर्न टाइप तय करता है.
इसके अलावा, रिटर्न टाइप को इनलाइन एनोटेट किया जा सकता है (उदाहरण में फ़ंक्शन
अगर externs में मौजूद नहीं है, तो फ़ंक्शन की कोई रिटर्न वैल्यू नहीं होती. ऐसे में, उदाहरण के लिए: /** * 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
|
इस टैग का इस्तेमाल, किसी फ़ंक्शन से मिले अपवादों को दस्तावेज़ में शामिल करने के लिए किया जाता है. फ़िलहाल, टाइप चेकर इस जानकारी का इस्तेमाल नहीं करता है. इसका इस्तेमाल सिर्फ़ यह पता लगाने के लिए किया जाता है कि किसी externs फ़ाइल में बताए गए फ़ंक्शन के साइड इफ़ेक्ट हैं या नहीं. उदाहरण के लिए: /** * @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
|
यह ज़्यादा जटिल टाइप के लिए, उपनाम तय करता है. फ़िलहाल, typedefs को सिर्फ़ टॉप लेवल पर तय किया जा सकता है, न कि फ़ंक्शन के अंदर. हमने टाइप इन्फ़रेंस की नई सुविधा में इस समस्या को ठीक कर दिया है. उदाहरण के लिए: /** @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
first parameter is documented as a callback that must take a number,
and we see f(function(x) { /** ... */ });
, then x must be
a number").
ऑपरेटर का नाम | सिंटैक्स के उदाहरण | ब्यौरा |
---|---|---|
नाम टाइप करें |
{boolean} {Window} {goog.ui.Menu}
|
किसी टाइप का नाम बताता है. |
ऐप्लिकेशन का टाइप |
{Array<string>} स्ट्रिंग का कलेक्शन.
|
टाइप को टाइप आर्ग्युमेंट के सेट के साथ पैरामीटर में बदलता है. Java के जेनेरिक से मिलता-जुलता है. |
यूनियन टाइप |
{(number|boolean)} कोई संख्या या बूलियन. ब्रैकेट का इस्तेमाल करना ज़रूरी है. |
इससे पता चलता है कि किसी वैल्यू का टाइप A या टाइप B हो सकता है. |
रिकॉर्ड टाइप |
{{myNum: number, myObject}}
एक एनॉनिमस टाइप, जिसमें myNum नाम की एक प्रॉपर्टी है. इसकी वैल्यू का टाइप number है. साथ ही, इसमें myObject नाम की एक प्रॉपर्टी है. इसकी वैल्यू का टाइप कोई भी हो सकता है.
|
इससे पता चलता है कि वैल्यू में बताए गए टाइप की वैल्यू वाले सदस्य मौजूद हैं. ब्रैसिस, टाइप सिंटैक्स का हिस्सा हैं. उदाहरण के लिए, |
नल वैल्यू स्वीकार करने वाला टाइप |
{?number} कोई संख्या या null .
|
इससे पता चलता है कि वैल्यू टाइप A या सभी ऑब्जेक्ट टाइप डिफ़ॉल्ट रूप से नल हो सकते हैं. भले ही, उन्हें Nullable ऑपरेटर के साथ घोषित किया गया हो या नहीं. ऑब्जेक्ट टाइप को इस तरह से परिभाषित किया जाता है: फ़ंक्शन, स्ट्रिंग, संख्या या बूलियन के अलावा कुछ भी. किसी ऑब्जेक्ट टाइप को नॉन-नलेबल बनाने के लिए, Non-nullable ऑपरेटर का इस्तेमाल करें. |
नॉन-नलेबल टाइप |
{!Object} एक ऑब्जेक्ट है, लेकिन कभी भी null वैल्यू नहीं है.
|
इससे पता चलता है कि वैल्यू टाइप A है और शून्य नहीं है. फ़ंक्शन और सभी वैल्यू टाइप (बूलियन, संख्या, और स्ट्रिंग) डिफ़ॉल्ट रूप से नॉन-नलेबल होते हैं. भले ही, उन्हें Non-nullable ऑपरेटर के साथ एलान किया गया हो या नहीं. किसी वैल्यू या फ़ंक्शन टाइप को नल वैल्यू के तौर पर इस्तेमाल करने के लिए, Nullable ऑपरेटर का इस्तेमाल करें. |
फ़ंक्शन टाइप |
{function(string, boolean)} यह फ़ंक्शन दो पैरामीटर (एक स्ट्रिंग और एक बूलियन) लेता है. इसकी रिटर्न वैल्यू के बारे में जानकारी नहीं है. |
यह फ़ंक्शन और फ़ंक्शन के पैरामीटर के टाइप तय करता है. |
फ़ंक्शन का रिटर्न टाइप |
{function(): number} यह एक ऐसा फ़ंक्शन है जो कोई पैरामीटर नहीं लेता और एक संख्या दिखाता है. |
किसी फ़ंक्शन की रिटर्न वैल्यू का टाइप तय करता है. |
फ़ंक्शन this टाइप |
{function(this:goog.ui.Menu, string)} यह फ़ंक्शन एक पैरामीटर (एक स्ट्रिंग) लेता है और goog.ui.Menu के कॉन्टेक्स्ट में काम करता है. |
फ़ंक्शन में this की वैल्यू का टाइप तय करता है. |
फ़ंक्शन new टाइप |
{function(new:goog.ui.Menu, string)} यह फ़ंक्शन एक पैरामीटर (एक स्ट्रिंग) लेता है. साथ ही, 'new' कीवर्ड के साथ कॉल किए जाने पर, goog.ui.Menu का नया इंस्टेंस बनाता है. |
यह कंस्ट्रक्टर के कंस्ट्रक्ट किए गए टाइप के बारे में बताता है. |
वैरिएबल पैरामीटर |
{function(string, ...number): number} यह फ़ंक्शन एक पैरामीटर (एक स्ट्रिंग) लेता है. इसके बाद, यह वैरिएबल नंबर वाले ऐसे पैरामीटर लेता है जो संख्याएं होनी चाहिए. |
इससे पता चलता है कि किसी फ़ंक्शन टाइप में, पैरामीटर की संख्या अलग-अलग हो सकती है. साथ ही, इससे वैरिएबल पैरामीटर के टाइप के बारे में भी पता चलता है. |
वैरिएबल पैरामीटर (@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=)} यह फ़ंक्शन, एक वैकल्पिक, नल हो सकने वाली स्ट्रिंग और एक वैकल्पिक संख्या को आर्ग्युमेंट के तौर पर लेता है. |
इससे पता चलता है कि फ़ंक्शन टाइप में कोई तर्क ज़रूरी नहीं है. फ़ंक्शन कॉल में, वैकल्पिक आर्ग्युमेंट को शामिल नहीं किया जा सकता. आर्ग्युमेंट की सूची में, ज़रूरी नहीं है कि आर्ग्युमेंट, ज़रूरी आर्ग्युमेंट से पहले हो. |
ALL टाइप | {*} |
इससे पता चलता है कि वैरिएबल किसी भी टाइप का हो सकता है. |
UNKNOWN टाइप | {?} |
इससे पता चलता है कि वेरिएबल किसी भी टाइप का हो सकता है. साथ ही, कंपाइलर को इसके किसी भी इस्तेमाल की टाइप-जांच नहीं करनी चाहिए. |
टाइप कास्टिंग
किसी वैल्यू को किसी खास टाइप में कास्ट करने के लिए, इस सिंटैक्स का इस्तेमाल करें
/** @type {!MyType} */ (valueExpression)
जेनरिक टाइप
Java की तरह ही, Closure Compiler में सामान्य टाइप, फ़ंक्शन, और तरीकों का इस्तेमाल किया जा सकता है. जेनेरिक, अलग-अलग टाइप के ऑब्जेक्ट पर काम करते हैं. साथ ही, कंपाइल-टाइम टाइप की सुरक्षा को बनाए रखते हैं.
जेनेरिक का इस्तेमाल करके, सामान्य कलेक्शन लागू किए जा सकते हैं. इनमें किसी खास टाइप के ऑब्जेक्ट के रेफ़रंस होते हैं. साथ ही, सामान्य एल्गोरिदम लागू किए जा सकते हैं. ये किसी खास टाइप के ऑब्जेक्ट पर काम करते हैं.
जेनेरिक टाइप का एलान करना
टाइप के कंस्ट्रक्टर (क्लास के लिए) या इंटरफ़ेस के एलान (इंटरफ़ेस के लिए) में @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());
ऊपर दिए गए दोनों कंस्ट्रक्टर स्टेटमेंट, 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>
के तौर पर लगाया जाता है.
एक से ज़्यादा टेंप्लेट टाइप
किसी सामान्य टेंप्लेट में, कई टेंप्लेट टाइप हो सकते हैं. नीचे दी गई मैप क्लास में दो तरह के टेंप्लेट होते हैं:
/** * @constructor * @template Key, Val */ MyMap = function() { ... };
किसी सामान्य टाइप के लिए, सभी टेंप्लेट टाइप को एक ही @template
एनोटेशन में कॉमा लगाकर अलग की गई सूची के तौर पर बताया जाना चाहिए. टेंप्लेट टाइप के नामों का क्रम ज़रूरी है, क्योंकि टेंप्लेट टाइप के एनोटेशन, टेंप्लेट टाइप को वैल्यू के साथ जोड़ने के लिए इस क्रम का इस्तेमाल करेंगे. उदाहरण के लिए:
/** @type {MyMap<string, number>} */ var map; // Key = string, Val = number.
जेनेरिक टाइप में इनवेरियंस
Closure Compiler, इनवेरिएंट जेनरिक टाइपिंग लागू करता है. इसका मतलब है कि अगर किसी कॉन्टेक्स्ट को Foo<X>
टाइप की ज़रूरत है, तो X
और Y
अलग-अलग टाइप होने पर, Foo<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