ध्यान दें: यह पेज पुराना है. पूरी सूची https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler में मैनेज की जाती है
खास जानकारी
क्लोज़र कंपाइलर, JavaScript वैरिएबल के बारे में डेटा टाइप की जानकारी का इस्तेमाल कर सकता है. इससे, बेहतर ऑप्टिमाइज़ेशन और चेतावनियां मिलती हैं. हालांकि, JavaScript में टाइप के बारे में बताने का कोई तरीका नहीं है.
JavaScript में किसी वैरिएबल के टाइप का एलान करने के लिए कोई सिंटैक्स नहीं है. इसलिए, डेटा टाइप के बारे में बताने के लिए, आपको कोड में टिप्पणियों का इस्तेमाल करना होगा.
क्लोज़र कंपाइलर के टाइप की भाषा, JSDoc दस्तावेज़ जनरेट करने वाले टूल में इस्तेमाल किए गए एनोटेशन से ली गई है. हालांकि, यह अब पहले से अलग है. अब इसमें ऐसे कई एनोटेशन शामिल हैं जो JSDoc में काम नहीं करते और इसका उलटा भी नहीं होता. इस दस्तावेज़ में, एनोटेशन और टाइप एक्सप्रेशन के उस सेट के बारे में बताया गया है जिसे क्लोज़र कंपाइलर समझता है.
JSDoc टैग
क्लोज़र कंपाइलर JSDoc टैग में टाइप की जानकारी खोजता है. कंपाइलर अपने कोड को ऑप्टिमाइज़ कर सकता है. साथ ही, संभावित गड़बड़ियों और दूसरी गलतियों की जांच करने के लिए, नीचे रेफ़रंस टेबल में दिए गए JSDoc टैग का इस्तेमाल करें.
इस टेबल में सिर्फ़ ऐसे टैग शामिल होते हैं जो क्लोज़र कंपाइलर के व्यवहार पर असर डालते हैं. अन्य 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 {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 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 {(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
टैग के साथ टाइप एक्सप्रेशन का इस्तेमाल करें.
कोड में जितनी ज़्यादा जानकारी दी जाएगी, कंपाइलर ज़्यादा से ज़्यादा ऑप्टिमाइज़ेशन का इस्तेमाल कर सकेंगे और उतनी ही ज़्यादा गलतियां पकड़ पाएंगे.
कंपाइलर आपके प्रोग्राम की टाइप-चेकिंग के लिए इन एनोटेशन का इस्तेमाल करता है.
ध्यान दें कि Close कंपाइलर यह वादा नहीं करता है कि
यह आपके प्रोग्राम में हर एक्सप्रेशन का टाइप तय कर पाएगा. यह सबसे अच्छा काम करता है. इसके लिए, वैरिएबल के इस्तेमाल और उनके एलान में अटैच किए गए एनोटेशन के बारे में पता लगाया जाता है. फिर यह ज़्यादा से ज़्यादा एक्सप्रेशन का टाइप पता करने के लिए, कई तरह के अनुमान वाले एल्गोरिदम का इस्तेमाल करता है. इनमें से कुछ
एल्गोरिदम सादगी भरे हैं (अगर x एक संख्या है और हमें
y = x;
दिखता है, तो y एक संख्या है). कुछ ज़्यादा इंडायरेक्ट होते हैं ("अगर f का पहला पैरामीटर कॉलबैक के रूप में दर्ज किया गया है, जिसे संख्या माननी है,
और हम f(function(x) { /** ... */ });
देखते हैं, तो x संख्या होना चाहिए").
ऑपरेटर का नाम | सिंटैक्स के उदाहरण | जानकारी |
---|---|---|
नाम लिखें |
{boolean} {Window} {goog.ui.Menu}
|
किसी टाइप का नाम बताता है. |
ऐप्लिकेशन किस तरह का है |
{Array<string>} स्ट्रिंग का अरे.
|
टाइप आर्ग्युमेंट के सेट की मदद से, टाइप को पैरामीटर बनाता है. यह Java की तरह है. |
प्रकार यूनियन |
{(number|boolean)} कोई संख्या या बूलियन. ऐसे ब्रैकेट नोट करें जो ज़रूरी हैं. |
यह बताता है कि किसी वैल्यू में टाइप A या टाइप B हो सकता है. |
रिकॉर्ड प्रकार |
{{myNum: number, myObject}}
बिना नाम वाली एक प्रॉपर्टी है जिसका नाम myNum है. इसमें number टाइप की वैल्यू और myObject नाम वाली प्रॉपर्टी है, जिसमें कोई भी वैल्यू दी जा सकती है.
|
यह बताता है कि वैल्यू में उसके तय किए गए सदस्य हैं और उनके पास तय किए गए टाइप की वैल्यू हैं. ब्रैकेट टाइप सिंटैक्स का हिस्सा हैं. उदाहरण के लिए, |
शून्य हो सकने वाला प्रकार |
{?number} कोई संख्या या null .
|
इससे पता चलता है कि वैल्यू A टाइप A या सभी तरह के ऑब्जेक्ट, डिफ़ॉल्ट रूप से शून्य होते हैं. भले ही, उन्हें शून्य करने वाले ऑपरेटर के साथ दिखाया गया हो या नहीं. ऑब्जेक्ट टाइप को फ़ंक्शन, स्ट्रिंग, संख्या या बूलियन को छोड़कर किसी भी तरह से परिभाषित किया जाता है. किसी ऑब्जेक्ट टाइप को शून्य नहीं करने के लिए, शून्य नहीं होने वाला ऑपरेटर का इस्तेमाल करें. |
गैर-शून्य प्रकार का |
{!Object} एक ऑब्जेक्ट, लेकिन null वैल्यू कभी नहीं.
|
इससे पता चलता है कि वैल्यू A टाइप है और शून्य नहीं है. फ़ंक्शन और सभी वैल्यू टाइप (बूलियन, नंबर, और स्ट्रिंग) डिफ़ॉल्ट रूप से शून्य नहीं होते. भले ही, उन्हें नॉन-नलेबल ऑपरेटर की मदद से तय किया गया हो या नहीं. किसी वैल्यू या फ़ंक्शन टाइप को शून्य करने लायक बनाने के लिए, Nullable ऑपरेटर का इस्तेमाल करें. |
फ़ंक्शन टाइप |
{function(string, boolean)} ऐसा फ़ंक्शन जो दो पैरामीटर (स्ट्रिंग और बूलियन) लेता है और उसकी वैल्यू नहीं पता होती. |
फ़ंक्शन और फ़ंक्शन के पैरामीटर के टाइप तय करता है. |
फ़ंक्शन रिटर्न टाइप |
{function(): number} ऐसा फ़ंक्शन जो कोई पैरामीटर नहीं लेता और कोई संख्या दिखाता है. |
फ़ंक्शन के रिटर्न वैल्यू का टाइप तय करता है. |
फ़ंक्शन this टाइप |
{function(this:goog.ui.Menu, string)} ऐसा फ़ंक्शन जो एक पैरामीटर (स्ट्रिंग) करता है और goog.ui.Menu के संदर्भ में काम करता है. |
फ़ंक्शन में this के मान का प्रकार
तय करता है. |
फ़ंक्शन new टाइप |
{function(new:goog.ui.Menu, string)} ऐसा फ़ंक्शन जो एक पैरामीटर (स्ट्रिंग) का इस्तेमाल करता है और 'नए' कीवर्ड के साथ कॉल करने पर नया 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 टाइप | {*} |
इससे पता चलता है कि वैरिएबल किसी भी टाइप का हो सकता है. |
अज्ञात प्रकार | {?} |
यह बताता है कि वैरिएबल को हर तरह के वैरिएबल पर ले जाया जा सकता है. साथ ही, कंपाइलर को इसके किसी भी टाइप की जांच नहीं करनी चाहिए. |
प्रकार कास्ट करना
किसी खास टाइप की वैल्यू को कास्ट करने के लिए, इस सिंटैक्स का इस्तेमाल करें
/** @type {!MyType} */ (valueExpression)एक्सप्रेशन के आस-पास वाले ब्रैकेट हमेशा ज़रूरी होते हैं.
जेनेरिक टाइप
Java की तरह, Closure कंपाइलर सामान्य प्रकार, फ़ंक्शन और विधियों का समर्थन करता है. जेनरिक, कई तरह के ऑब्जेक्ट के लिए काम करते हैं. साथ ही, कंपाइल के समय की सुरक्षा देते हैं.
सामान्य ऑब्जेक्ट का संग्रह इस्तेमाल करने के लिए जेनरिक का इस्तेमाल किया जा सकता है. ये कलेक्शन एक खास तरह के ऑब्जेक्ट के रेफ़रंस के तौर पर होते हैं. इसके अलावा, सामान्य एल्गोरिदम का इस्तेमाल किसी खास तरह के ऑब्जेक्ट के लिए किया जाता है.
सामान्य टाइप का एलान
टाइप के कंस्ट्रक्टर (कक्षा के लिए) में @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.
जेनरिक टाइप का अंतर
क्लोज़र कंपाइलर, सामान्य जेनरिक टाइपिंग लागू करता है. इसका मतलब है कि अगर किसी संदर्भ में 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