Uwaga: ta strona jest nieaktualna. Pełną listę znajdziesz na https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler
Omówienie
Kompilator Closure może wykorzystywać informacje o typie danych zmiennych JavaScriptu, aby ulepszać optymalizację i ostrzeżenia. JavaScriptu nie można jednak deklarować.
JavaScript nie ma składni do zadeklarowania typu zmiennej, więc aby określić typ danych, musisz użyć komentarzy w kodzie.
Język używany w komponencie Closure Compiler pochodzi z adnotacji używanych w narzędziu do generowania dokumentów JSDoc, chociaż od tamtego czasu jest nieco bardziej rozpowszechniony. Zawiera teraz kilka adnotacji, których JSDoc nie obsługuje, i odwrotnie. Ten dokument opisuje zestaw adnotacji i wyrażeń typu zrozumiałych dla kompilatora Closure.
Tagi JSDoc
Kompilator zamknięty wyszukuje informacje o typie w tagach JSDoc. Użyj tagów JSDoc opisanych w tabeli poniżej, aby ułatwić kompilatorowi optymalizację kodu i sprawdzenie, czy nie występują w nim błędy.
Ta tabela zawiera tylko tagi, które mają wpływ na zachowanie kompozytora Closure. Informacje o innych tagach JSDoc znajdziesz w dokumentacji zestawu narzędzi JSDoc.
Tag | Opis |
---|---|
@abstract
|
Oznacza metodę jako abstrakcyjną. Kompilator może przypominać metody z właściwością
Kompilator wyświetla ostrzeżenie, jeśli metoda oznaczona jako /** @abstract */ foo.MyClass.prototype.abstractMethod = function() {}; |
@const
|
Oznacza zmienną jako tylko do odczytu. Kompilator może umieścić zmienne Deklaracja typu jest opcjonalna.
Kompilator generuje ostrzeżenie, jeśli do zmiennej oznaczonej wartością /** @const */ var MY_BEER = 'stout'; /** * My namespace's favorite kind of beer. * @const {string} */ mynamespace.MY_BEER = 'stout'; /** @const */ MyClass.MY_BEER = 'stout'; |
@constructor
|
Oznacza funkcję jako konstruktor.
Kompilator wymaga adnotacji Przykład: /** * A rectangle. * @constructor */ function GM_Rect() { ... } |
@define
|
Wskazuje stałą, którą kompilator może zastąpić w czasie kompilacji.
W przykładzie po lewej stronie możesz przekazać flagę --define='ENABLE_DEBUG=false', by zmienić wartość ENABLE_DEBUG na false.
Definicją stałej może być liczba, ciąg lub wartość logiczna.
Definicje są dozwolone tylko w zakresie globalnym.
Przykład: /** @define {boolean} */ var ENABLE_DEBUG = true; /** @define {boolean} */ goog.userAgent.ASSUME_IE = false; |
@deprecated
|
Oznacza funkcję, metodę lub właściwość w taki sposób, aby podczas korzystania z niego tworzone było ostrzeżenie dotyczące kompilatora wskazującego, że narzędzie nie jest już potrzebne. Przykład: /** * 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
|
Przykład: /** * @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
|
Określa typ wyliczenia. Wyliczenie to obiekt, którego właściwości tworzą zbiór powiązanych ze sobą stałych. Po tagu Etykieta typu wyliczenia ma zastosowanie do każdej właściwości wyliczenia. Jeśli na przykład wyliczenie zawiera typ Przykład: /** * Enum for tri-state values. * @enum {number} */ project.TriState = { TRUE: 1, FALSE: -1, MAYBE: 0 }; |
@export
|
Podany kod /** @export */ foo.MyPublicClass.prototype.myPublicMethod = function() { // ... };
Po uruchomieniu kompilatora z flagą goog.exportProperty(foo.MyPublicClass.prototype, 'myPublicMethod', foo.MyPublicClass.prototype.myPublicMethod); co spowoduje wyeksportowanie ich do nieskompilowanego kodu. Możesz napisać
/** * @export * @type {SomeType} */ Kod korzystający z adnotacji
|
@extends
|
Oznacza zajęcia lub interfejs jako dziedziczone z innych. Klasa oznaczona etykietą
Uwaga:
Przykład implementacji dziedziczenia znajdziesz w funkcji biblioteki Closure Przykład: /** * Immutable empty node list. * @constructor * @extends {goog.ds.BasicNodeList} */ goog.ds.EmptyNodeList = function() { ... }; |
@final
|
Oznacza, że tych zajęć nie można przedłużyć. W przypadku metod oznacza, że żadna podklasa nie może zastąpić tej metody. Przykład: /** * A class that cannot be extended. * @final * @constructor */ sloth.MyFinalClass = function() { ... } /** * A method that cannot be overridden. * @final */ sloth.MyFinalClass.prototype.method = function() { ... }; |
@implements
|
Użycie razem z znacznikiem
Kompilator generuje ostrzeżenie, jeśli oznaczysz konstruktor tagiem Przykład: /** * A shape. * @interface */ function Shape() {}; Shape.prototype.draw = function() {}; /** * @constructor * @implements {Shape} */ function Square() {}; Square.prototype.draw = function() { ... }; |
@implicitCast
|
Ta adnotacja może pojawić się tylko w deklaracjach właściwości rozszerzeń.
Właściwość ma zadeklarowany typ, ale możesz przypisać do niego dowolny typ bez ostrzeżenia. Gdy uzyskujesz dostęp do usługi, zwracana jest wartość zadeklarowanego typu. Na przykład /** * @type {string} * @implicitCast */ Element.prototype.innerHTML; |
@inheritDoc
|
Wskazuje, że metoda lub właściwość klasy podrzędnej celowo ukrywa metodę lub właściwość klasy premium i ma dokładnie taką samą dokumentację. Pamiętaj, że tag Przykład: /** @inheritDoc */ project.SubClass.prototype.toString = function() { ... }; |
@interface
|
Oznacza funkcję jako interfejs. Interfejs określa wymaganych członków typu. Każda klasa, która korzysta z interfejsu, musi implementować wszystkie metody i właściwości zdefiniowane w prototypie interfejsu. Zobacz
Kompilator sprawdza, czy nie utworzono instancji interfejsu. Jeśli słowo kluczowe Przykład: /** * A shape. * @interface */ function Shape() {}; Shape.prototype.draw = function() {}; /** * A polygon. * @interface * @extends {Shape} */ function Polygon() {}; Polygon.prototype.getSides = function() {}; |
@lends
|
Wskazuje, że klucze literału obiektu powinny być traktowane jako właściwości innego obiektu. Ta adnotacja powinna się pojawić tylko w literałach obiektów.
Nazwa w nawiasach klamrowych nie jest nazwą tego typu, jak w przypadku innych adnotacji. Jest to nazwa obiektu. Określa obiekt, do którego pożyczone są właściwości.
Na przykład Więcej informacji o tej adnotacji znajdziesz w dokumentacji JSDoc Toolkit. Przykład: goog.object.extend( Button.prototype, /** @lends {Button.prototype} */ ({ isButton: function() { return true; } })); |
@license lub @preserve
|
Mówi kompilatorowi, aby wstawił powiązany komentarz przed skompilowanym kodem zaznaczonego pliku. Ta adnotacja pozwala zachować ważne informacje (takie jak licencje lub tekst praw autorskich) bez zmian kompilacji. Podziały wiersza są zachowywane. Przykład: /** * @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
|
Oznacza właściwość, która nie powinna być zwinięta przez kompilator w zmienną. Głównym zastosowaniem w Przykład: /** * A namespace. * @const */ var foo = {}; /** * @nocollapse */ foo.bar = 42; window['foobar'] = foo.bar; |
@nosideeffects
|
Wskazuje, że wywołanie zadeklarowanej funkcji zewnętrznej nie ma żadnych efektów ubocznych.
Jeżeli ta wartość nie jest używana, kompilator może usunąć wywołania funkcji. Adnotacja jest dozwolona tylko w
Przykład: /** @nosideeffects */ function noSideEffectsFn1() {} /** @nosideeffects */ var noSideEffectsFn2 = function() {}; /** @nosideeffects */ a.prototype.noSideEffectsFn3 = function() {}; |
@override
|
Wskazuje, że metoda lub właściwość podklasy jest celowo ukrywa metodę lub właściwość klasy nadklasowej. Jeśli nie dodasz żadnych innych adnotacji, metoda lub właściwość automatycznie dziedziczy adnotacje z klasy nadrzędnej. Przykład: /** * @return {string} Human-readable representation of * project.SubClass. * @override */ project.SubClass.prototype.toString = function() { ... }; |
@package
|
Oznacza członka lub usługę jako prywatne. Dostęp do nazw oznaczonych jako
Konstruktory publiczne mogą mieć właściwości Przykład: /** * 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
|
Używane są z użyciem metody, funkcji i konstruktora w celu określenia typów argumentów funkcji. Tagi
Po tagu
Możesz też dodać adnotacje do typów parametrów w tekście (zobacz funkcję Przykład: /** * 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; }W przypadku parametrów o niszczycielskim wzorcu możesz użyć dowolnej nazwy, która jest prawidłowym identyfikatorem JS. /** * @param {{name: string, age: number}} person */ function logPerson({name, age}) { console.log(`${name} is ${age} years old`); } |
@private
|
Oznacza członka jako prywatnego. Dostęp do zmiennych i funkcji globalnych oznaczonych jako
Publiczne właściwości statyczne konstruktorów oznaczonych jako Przykład: /** * Handlers that are listening to this logger. * @private {Array<Function>} */ this.handlers_ = []; |
@protected
|
Wskazuje, że użytkownik lub usługa są chronione.
Usługa oznaczona jako
Przykład: /** * 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
|
Oznacza funkcję jako interfejs strukturalny. Interfejs strukturalny jest podobny do nominalnego Przykład: /** * 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
|
Określa typy zwracanych definicji metody i funkcji.
Po tagu
Możesz też dodać opis typu zwrotu w tekście (zobacz funkcję
Jeśli funkcja, która nie jest zewnętrzne, nie ma wartości zwracającej, możesz pominąć tag Przykład: /** * 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
|
Przykład: /** * @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
|
Zobacz Typy ogólne. Przykład: /** * @param {T} t * @constructor * @template T */ Container = function(t) { ... }; |
@this
|
Określa typ obiektu, do którego odnosi się słowo kluczowe
Aby uniknąć ostrzeżeń dotyczących kompilacji, musisz użyć adnotacji Przykład: chat.RosterWidget.extern('getRosterElement', /** * Returns the roster widget element. * @this {Widget} * @return {Element} */ function() { return this.getComponent().getElement(); }); |
@throws
|
Służy do dokumentowania wyjątków zgłoszonych przez funkcję. Obecnie ta funkcja nie korzysta z tych informacji. Służy on wyłącznie do sprawdzania, czy funkcja zadeklarowana w pliku rozszerzeń ma efekty uboczne. Przykład: /** * @throws {DOMException} */ DOMApplicationCache.prototype.swapCache = function() { ... }; |
@type
|
Określa typ zmiennej, właściwości lub wyrażenia. Po tagu Podczas deklarowania zmiennej lub parametru funkcji możesz dodać w tekście adnotację typu, pomijając elementy Przykład: /** * The message hex ID. * @type {string} */ var hexId = hexId; var /** string */ name = 'Jamie'; function useSomething(/** (string|number|!Object) */ something) { ... } |
@typedef
|
Deklaruje alias dla bardziej złożonego typu. Obecnie typy typedef można definiować tylko na najwyższym poziomie, a nie wewnątrz funkcji. Naprawiliśmy to ograniczenie w nowej wnioskowaniu typu. Przykład: /** @typedef {(string|number)} */ goog.NumberLike; /** @param {goog.NumberLike} x A number or a string. */ goog.readNumber = function(x) { ... } |
@unrestricted
|
Wskazuje, że klasa nie jest typu Przykład: /** * @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 |
Wyrażenia typu
Typ danych dowolnej zmiennej, właściwości, wyrażenia lub parametru funkcji możesz określić za pomocą wyrażenia typu. Wyrażenie typu składa się z nawiasów klamrowych („{ }”) zawierających kombinację kombinacji operatorów opisanych poniżej.
Zadeklaruj typ parametru funkcji za pomocą wyrażenia typu z tagiem @param
. Aby zdefiniować typ zmiennej, właściwości lub wyrażenia, użyj wyrażenia typu z tagiem @type
.
Im więcej typów określisz w kodzie, tym więcej optymalizacji może wykonać kompilator i tym więcej błędów może wykryć.
Kompilator wykorzystuje te adnotacje do sprawdzania typu programu.
Pamiętaj, że kompilator Closure nie zawiera żadnych obietnic, że będzie w stanie znaleźć typ każdego wyrażenia w programie. Najlepiej zrobić to, sprawdzając, jak używane są zmienne i jakie adnotacje są powiązane z ich deklaracjami. Następnie używa wielu algorytmów wnioskowania dotyczących typu, aby określić rodzaj jak największej liczby wyrażeń. Niektóre z tych algorytmów są proste („jeśli x to liczba, a my to y = x;
, to y to liczba”). Niektóre z nich są bardziej pośrednie („jeśli pierwszy parametr f jest udokumentowany jako wywołanie zwrotne, które musi przyjmować liczbę, a widzimy f(function(x) { /** ... */ });
, wtedy x musi być liczbą”).
Nazwa operatora | Przykłady składni | Opis |
---|---|---|
Nazwa typu |
{boolean} {Window} {goog.ui.Menu}
|
Określa nazwę typu. |
Typ aplikacji |
{Array<string>} Tablica ciągów tekstowych.
|
Parametr określa typ za pomocą zestawu argumentów typu. To coś podobnego do Javy. |
Typ: związki |
{(number|boolean)} Liczba lub wartość logiczna. Wymagane nawiasy kwadratowe. |
Wskazuje, że wartość może zawierać typ A LUB typ B. |
Typ rekordu |
{{myNum: number, myObject}}
Anonimowy typ z usługą myNum , która ma wartość typu number , i usługą o nazwie myObject , która ma wartość dowolnego typu.
|
Wskazuje, że wartość ma określonych członków z wartościami określonych typów. Aparaty ortodontyczne są częścią składni typu. Aby wskazać na przykład obiekt |
Typ null |
{?number} Liczba lub null .
|
Wskazuje, że wartość jest typem A lub Wszystkie typy obiektów są domyślnie puste, niezależnie od tego, czy zostały zadeklarowane za pomocą operatora null. Typ obiektu to dowolny obiekt oprócz funkcji, ciągu, liczby lub wartości logicznej. Aby typ obiektu nie był null, użyj operatora nienull. |
Nie dopuszcza się wartości null |
{!Object} Obiekt, ale nigdy wartość null .
|
Wskazuje, że wartość jest typu A, a nie jest pusta. Funkcje i wszystkie typy wartości (wartość logiczna, liczba i ciąg) nie są domyślnie puste, niezależnie od tego, czy zostały zadeklarowane za pomocą operatora bez wartości null. Aby wartość lub typ funkcji miał wartość null, użyj operatora nullable. |
Typ funkcji |
{function(string, boolean)} Funkcja, która przyjmuje 2 parametry (ciąg i wartość logiczna) i ma nieznaną wartość zwrotną. |
Określa funkcję i typy parametrów funkcji. |
Typ zwracania funkcji |
{function(): number} Funkcja, która nie przyjmuje parametrów i zwraca liczbę. |
Określa typ zwracanej wartości funkcji. |
Typ funkcji this |
{function(this:goog.ui.Menu, string)} Funkcja, która przyjmuje jeden parametr (ciąg znaków) i wykonuje się w kontekście kontekstu goog.ui.Menu. |
Określa typ wartości this w funkcji. |
Typ funkcji new |
{function(new:goog.ui.Menu, string)} Funkcja, która przyjmuje jeden parametr (ciąg znaków) i tworzy nowe wystąpienie tagu goog.ui.Menu po wywołaniu za pomocą słowa kluczowego „nowe”. |
Określa typ konstruktora. |
Parametry zmiennej |
{function(string, ...number): number} Funkcja, która przyjmuje jeden parametr (ciąg znaków), a następnie zmienną liczbę parametrów, które muszą być liczbami. |
Wskazuje, że typ funkcji przyjmuje zmienną liczbę parametrów i określa typ parametrów zmiennych. |
Parametry zmiennej (w @param adnotacjach)
|
@param {...number} var_args Zmienna liczba parametrów na funkcję z adnotacjami. |
Wskazuje, że funkcja z adnotacjami akceptuje zmienną liczbę parametrów i określa ich typ. |
Opcjonalny parametr w adnotacji @param
|
@param {number=} opt_argument Opcjonalny parametr typu number .
|
Argument wskazuje, że argument opisany w adnotacji
Jeśli wywołanie metody pomija parametr opcjonalny, ma on wartość /** * 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; } |
Opcjonalny argument w typie funkcji |
{function(?string=, number=)} Funkcja, która przyjmuje 1 opcjonalny ciąg znaków o wartości null i 1 opcjonalną liczbę jako argumenty. |
Wskazuje, że argument w typie funkcji jest opcjonalny. Opcjonalny argument można pominąć z wywołania funkcji. Opcjonalny argument nie może poprzedzać opcjonalnego argumentu na liście argumentów. |
Typ WSZYSTKO | {*} |
Wskazuje, że zmienna może przyjmować dowolny typ. |
Typ NIEZNANY | {?} |
Wskazuje, że zmienna może przyjąć dowolny typ, a kompilator nie powinien sprawdzać, czy ma ona jakiekolwiek zastosowania. |
Typ przesyłania
Aby przesłać wartość do określonego typu, użyj tej składni
/** @type {!MyType} */ (valueExpression)Nawiasy wokół wyrażenia są zawsze wymagane.
Typy ogólne
Podobnie jak w przypadku Javy, Closure Compiler obsługuje ogólne typy, funkcje i metody. Ogólne działają na obiektach różnego typu, a jednocześnie zachowują bezpieczeństwo podczas kompilacji.
Za ich pomocą możesz wdrożyć uogólnione kolekcje zawierające odwołania do obiektów określonego typu oraz uogólnione algorytmy działające na obiektach danego typu.
Deklarowanie typu ogólnego
Typ można ustawić jako ogólny, dodając adnotację @template
do konstruktora typu (w przypadku klas) lub w deklaracji interfejsu (w przypadku interfejsów). Przykład:
/** * @constructor * @template T */ Foo = function() { ... };
Adnotacja @template T
wskazuje, że typ Foo
ma typ ogólny i 1 szablon (T
).
Typu szablonu T
można używać jako typu w zakresie definicji Foo
. Przykład:
/** @return {T} */ Foo.prototype.get = function() { ... }; /** @param {T} t */ Foo.prototype.set = function(t) { ... };
Metoda get
zwraca obiekt typu T
, a metoda set
akceptuje tylko obiekty typu T
.
Tworzenie instancji typu ogólnego
Ten sam przykład: Foo
można utworzyć na kilka sposobów:
/** @type {!Foo<string>} */ var foo = new Foo(); var foo = /** @type {!Foo<string>} */ (new Foo());
Oba powyższe wyrażenia konstruktora tworzą instancję Foo
, której szablon T
to string
. Kompilator wymusi wywoływanie metod foo
i dostęp do właściwości foo
z uwzględnieniem szablonu. Przykład:
foo.set("hello"); // OK. foo.set(3); // Error - expected a string, found a number. var x = foo.get(); // x is a string.
Instancje mogą też domyślnie być wpisane przez argumenty ich konstruktora.
Rozważ inny typ (Bar
):
/** * @param {T} t * @constructor * @template T */ Bar = function(t) { ... }; var bar = new Bar("hello"); // bar is a Bar<string>
Typ argumentu konstruktora Bar
jest określany jako string
, w wyniku czego utworzona instancja bar
jest traktowana jako Bar<string>
.
Wiele typów szablonów
Ogólny może mieć dowolną liczbę typów szablonów. Ta klasa mapy ma dwa typy szablonów:
/** * @constructor * @template Key, Val */ MyMap = function() { ... };
Wszystkie typy szablonów ogólnych muszą być określone w tej samej adnotacji @template
, w formie listy rozdzielanej przecinkami. Kolejność nazw typów szablonów jest ważna, ponieważ adnotacje na podstawie szablonu będą grupować typy szablonów z wartościami. Przykład:
/** @type {MyMap<string, number>} */ var map; // Key = string, Val = number.
Różnica typów ogólnych
Kompilator zamknięty egzekwuje pisanie ogólne. Oznacza to, że jeśli kontekst oczekuje elementu Foo<X>
, nie możesz przekazać typu Foo<Y>
, gdy X
i Y
są różne, nawet jeśli jeden jest podtypem. Przykład:
/** * @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
Dziedziczenie typów ogólnych
Typy ogólne mogą być dziedziczone, a ich typy szablonów można naprawić lub rozpowszechnić w ramach dziedziczenia. Oto przykład typu dziedziczenia, który naprawia typ szablonu jego supertypu:
/** * @constructor * @template T */ A = function() { ... }; /** @param {T} t */ A.prototype.method = function(t) { ... }; /** * @constructor * @extends {A<string>} */ B = function() { ... };
Po rozszerzeniu A<string>
B
będzie zawierać metodę method
, która przyjmuje parametr typu string
.
Oto przykład typu dziedziczenia, który rozpowszechnia ten typ szablonu:
/** * @constructor * @template U * @extends {A<U>} */ C = function() { ... };
Po rozszerzeniu A<U>
wystąpienia szablonu C
będą miały metodę method
, która przyjmuje parametr typu szablonu U
.
Interfejsy można implementować i rozszerzać w podobny sposób. Jeden typ nie może być kilkukrotnie implementowany z różnym typem szablonu. Przykład:
/** * @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
Funkcje i metody ogólne
Podobnie jak w przypadku typów ogólnych, funkcje i metody można nadać ogólny charakter, dodając do definicji adnotację @template
. Przykład:
/** * @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