Uwaga: ta strona jest nieaktualna. Pełna lista jest dostępna na stronie https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler
Przegląd
Kompilator Closure może używać informacji o typach danych zmiennych JavaScript, aby zapewniać lepszą optymalizację i ostrzeżenia. JavaScript nie ma jednak możliwości deklarowania typów.
JavaScript nie ma składni deklarowania typu zmiennej, dlatego musisz używać komentarzy w kodzie, aby określać typ danych.
Język typów kompilatora Closure Compiler wywodzi się z adnotacji używanych przez narzędzie do generowania dokumentów JSDoc, ale od tego czasu uległ zmianie. Zawiera teraz kilka adnotacji, których JSDoc nie obsługuje, i odwrotnie. W tym dokumencie opisujemy zestaw adnotacji i wyrażeń typów, które rozumie kompilator Closure Compiler.
Tagi JSDoc
Kompilator Closure Compiler szuka informacji o typach w tagach JSDoc. Używaj tagów JSDoc opisanych w tabeli referencyjnej poniżej, aby pomóc kompilatorowi zoptymalizować kod i sprawdzić go pod kątem możliwych błędów typów i innych błędów.
Ta tabela zawiera tylko tagi, które wpływają na działanie kompilatora Closure Compiler. Informacje o innych tagach JSDoc znajdziesz w dokumentacji JSDoc Toolkit.
Tag | Opis |
---|---|
@abstract
|
Oznacza metodę jako abstrakcyjną. Podobnie jak w przypadku ustawienia metody na
Jeśli metoda oznaczona adnotacją /** @abstract */ foo.MyClass.prototype.abstractMethod = function() {}; |
@const
|
Oznacza zmienną jako tylko do odczytu. Kompilator może wstawiać zmienne w kodzie, co optymalizuje kod JavaScript. Deklaracja typu jest opcjonalna.
Kompilator wyświetla ostrzeżenie, jeśli zmiennej oznaczonej symbolem /** @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 Na 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ć do kompilatora flagę --define='ENABLE_DEBUG=false', aby zmienić wartość ENABLE_DEBUG na false.
Typ zdefiniowanej stałej może być liczbowy, tekstowy lub logiczny.
Definicje są dozwolone tylko w zakresie globalnym.
Na przykład: /** @define {boolean} */ var ENABLE_DEBUG = true; /** @define {boolean} */ goog.userAgent.ASSUME_IE = false; |
@deprecated
|
Oznacza funkcję, metodę lub właściwość, tak aby jej użycie powodowało ostrzeżenie kompilatora wskazujące, że nie należy jej już używać. Na 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
|
Na 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 stanowią zbiór powiązanych stałych. Po tagu Etykieta typu wyliczenia dotyczy każdej właściwości wyliczenia. Jeśli np. wyliczenie ma typ Na przykład: /** * Enum for tri-state values. * @enum {number} */ project.TriState = { TRUE: 1, FALSE: -1, MAYBE: 0 }; |
@export
|
Dany kod /** @export */ foo.MyPublicClass.prototype.myPublicMethod = function() { // ... };
Gdy kompilator jest uruchamiany z flagą goog.exportProperty(foo.MyPublicClass.prototype, 'myPublicMethod', foo.MyPublicClass.prototype.myPublicMethod); spowoduje wyeksportowanie symboli do nieskompilowanego kodu. Możesz napisać
/** * @export * @type {SomeType} */ Kod, który używa adnotacji
|
@extends
|
Oznacza, że klasa lub interfejs dziedziczy po innej klasie. Klasa oznaczona wartością
Uwaga:
Przykład implementacji dziedziczenia znajdziesz w funkcji Na przykład: /** * Immutable empty node list. * @constructor * @extends {goog.ds.BasicNodeList} */ goog.ds.EmptyNodeList = function() { ... }; |
@final
|
Wskazuje, że tej klasy nie można rozszerzyć. W przypadku metod oznacza, że żadna podklasa nie może zastąpić tej metody. Na 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żywany z symbolem
Jeśli oznaczysz konstruktor za pomocą Na 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 pojawiać się tylko w deklaracjach właściwości externs.
Właściwość ma zadeklarowany typ, ale możesz przypisać do niej dowolny typ bez ostrzeżenia. Gdy uzyskasz dostęp do właściwości, otrzymasz wartość zadeklarowanego typu. Na przykład zmiennej /** * @type {string} * @implicitCast */ Element.prototype.innerHTML; |
@inheritDoc
|
Wskazuje, że metoda lub właściwość podklasy celowo ukrywa metodę lub właściwość nadklasy i ma dokładnie taką samą dokumentację. Pamiętaj, że tag Na 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 implementuje interfejs, musi implementować wszystkie metody i właściwości zdefiniowane w prototypie interfejsu. Zobacz
Kompilator sprawdza, czy interfejsy nie są tworzone. Jeśli słowo kluczowe Na 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 pojawiać się tylko w przypadku literałów obiektów.
Zwróć uwagę, że nazwa w nawiasach klamrowych nie jest nazwą typu, jak w przypadku innych adnotacji. Jest to nazwa obiektu. Określa obiekt, do którego odnoszą się właściwości.
Na przykład Więcej informacji o tej adnotacji znajdziesz w dokumentacji JSDoc Toolkit. Na przykład: goog.object.extend( Button.prototype, /** @lends {Button.prototype} */ ({ isButton: function() { return true; } })); |
@license lub @preserve
|
Nakazuje kompilatorowi wstawić powiązany komentarz przed skompilowanym kodem oznaczonego pliku. Ta adnotacja umożliwia zachowanie ważnych informacji (takich jak licencje prawne lub tekst dotyczący praw autorskich) bez zmian po skompilowaniu. Podziały wierszy są zachowywane. Na 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ć zwijana przez kompilator do zmiennej. Głównym zastosowaniem Na 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 efektów ubocznych.
Ta adnotacja umożliwia kompilatorowi usuwanie wywołań funkcji, jeśli wartość zwracana nie jest używana. Adnotacja jest dozwolona tylko w przypadku Na przykład: /** @nosideeffects */ function noSideEffectsFn1() {} /** @nosideeffects */ var noSideEffectsFn2 = function() {}; /** @nosideeffects */ a.prototype.noSideEffectsFn3 = function() {}; |
@override
|
Wskazuje, że metoda lub właściwość podklasy celowo ukrywa metodę lub właściwość klasy nadrzędnej. Jeśli nie ma innych adnotacji, metoda lub właściwość automatycznie dziedziczy adnotacje z klasy nadrzędnej. Na przykład: /** * @return {string} Human-readable representation of * project.SubClass. * @override */ project.SubClass.prototype.toString = function() { ... }; |
@package
|
Oznacza element lub właściwość jako dostępne tylko w pakiecie. Tylko kod w tym samym katalogu może uzyskiwać dostęp do nazw oznaczonych symbolem
Konstruktory publiczne mogą mieć właściwości Na 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 w definicjach metod, funkcji i konstruktorów do określania typów argumentów funkcji. Tagi
Po tagu
Możesz też dodać adnotacje do typów parametrów w tekście (patrz funkcja Na 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; } /** * @param {{name: string, age: number}} person */ function logPerson({name, age}) { console.log(`${name} is ${age} years old`); } |
@private
|
Oznacza użytkownika jako prywatnego. Tylko kod w tym samym pliku może uzyskiwać dostęp do zmiennych globalnych i funkcji oznaczonych jako
Do publicznych właściwości statycznych konstruktorów oznaczonych symbolem Na przykład: /** * Handlers that are listening to this logger. * @private {Array<Function>} */ this.handlers_ = []; |
@protected
|
Wskazuje, że członek lub usługa są chronione.
Usługa oznaczona symbolem
Na 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 interfejsu nominalnego Na 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 zwracane przez definicje metod i funkcji.
Po tagu
Możesz też dodać adnotację do typu zwracanego w tekście (patrz funkcja
Jeśli funkcja, która nie znajduje się w pliku externs, nie zwraca żadnej wartości, możesz pominąć tag
Na 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
|
Na 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. Na 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 zapobiec ostrzeżeniom kompilatora, musisz używać adnotacji Na 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łaszanych przez funkcję. Sprawdzanie typów nie korzysta obecnie z tych informacji. Jest używana tylko do określania, czy funkcja zadeklarowana w pliku externs ma efekty uboczne. Na 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 zapisać adnotację typu w wierszu, pomijając znaki Na 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 w funkcjach. Usunęliśmy to ograniczenie w nowym wnioskowaniu o typach. Na 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 Na 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 („{ }”), które zawierają kombinację operatorów typu opisanych poniżej.
Użyj wyrażenia typu z tagiem @param
, aby zadeklarować typ parametru funkcji. Użyj wyrażenia typu z tagiem @type
, aby zadeklarować typ zmiennej, właściwości lub wyrażenia.
Im więcej typów określisz w kodzie, tym więcej optymalizacji może wprowadzić kompilator i tym więcej błędów może wykryć.
Kompilator używa tych adnotacji do sprawdzania typów w programie.
Pamiętaj, że kompilator Closure nie gwarantuje, że będzie w stanie określić typ każdego wyrażenia w Twoim programie. W tym celu analizuje sposób użycia zmiennych i adnotacje o typach dołączone do ich deklaracji. Następnie używa kilku algorytmów wnioskowania o typach, aby określić typ jak największej liczby wyrażeń. Niektóre z tych algorytmów są proste („jeśli x jest liczbą i widzimy y = x;
, to y jest liczbą”). Niektóre są bardziej pośrednie („jeśli pierwszy parametr funkcji f jest udokumentowany jako wywołanie zwrotne, które musi przyjmować liczbę, a widzimy f(function(x) { /** ... */ });
, to x musi być liczbą”).
Nazwa operatora | Przykłady składni | Opis |
---|---|---|
Wpisz nazwę |
{boolean} {Window} {goog.ui.Menu}
|
Określa nazwę typu. |
Wpisz nazwę aplikacji |
{Array<string>} Tablica ciągów znaków.
|
Parametryzuje typ za pomocą zestawu argumentów typu. Podobnie jak w przypadku typów generycznych w Javie. |
Typ Union |
{(number|boolean)} Liczba lub wartość logiczna. Zwróć uwagę na nawiasy, które są wymagane. |
Wskazuje, że wartość może mieć typ A LUB typ B. |
Typ rekordu |
{{myNum: number, myObject}}
Typ anonimowy z właściwością o nazwie myNum
i wartości typu number oraz właściwością o nazwie myObject i wartości dowolnego typu.
|
Wskazuje, że wartość ma określonych członków z wartościami określonych typów. Nawiasy klamrowe są częścią składni typu. Aby na przykład oznaczyć |
Typ dopuszczający wartość null |
{?number} Liczba lub null .
|
Wskazuje, że wartość jest typu A lub Domyślnie wszystkie typy obiektów mogą mieć wartość null, niezależnie od tego, czy zostały zadeklarowane za pomocą operatora Nullable. Typ obiektu to wszystko z wyjątkiem funkcji, ciągu znaków, liczby lub wartości logicznej. Aby ustawić typ obiektu jako nieakceptujący wartości null, użyj operatora Non-nullable. |
Typ nieakceptujący wartości null |
{!Object} Obiekt, ale nigdy wartość null .
|
Wskazuje, że wartość jest typu A i nie jest wartością null. Funkcje i wszystkie typy wartości (logiczne, liczbowe i ciągi znaków) domyślnie nie mogą mieć wartości null, niezależnie od tego, czy są zadeklarowane za pomocą operatora Non-nullable. Aby umożliwić przyjmowanie wartości null przez typ wartości lub funkcji, użyj operatora Nullable. |
Typ funkcji |
{function(string, boolean)} Funkcja, która przyjmuje 2 parametry (ciąg znaków i wartość logiczną) i ma nieznaną wartość zwrotną. |
Określa funkcję i typy parametrów funkcji. |
Typ zwracany przez funkcję |
{function(): number} Funkcja, która nie przyjmuje żadnych parametrów i zwraca liczbę. |
Określa typ wartości zwracanej funkcji. |
Funkcja this Typ |
{function(this:goog.ui.Menu, string)} Funkcja, która przyjmuje jeden parametr (ciąg znaków) i jest wykonywana w kontekście goog.ui.Menu. |
Określa typ wartości this w funkcji. |
Funkcja new Typ |
{function(new:goog.ui.Menu, string)} Funkcja, która przyjmuje 1 parametr (ciąg znaków) i tworzy nową instancję goog.ui.Menu, gdy jest wywoływana ze słowem kluczowym „new”. |
Określa skonstruowany typ konstruktora. |
Parametry zmienne |
{function(string, ...number): number} Funkcja, która przyjmuje 1 parametr (ciąg znaków), a potem 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 zmienne (w adnotacjach @param )
|
@param {...number} var_args Zmienna liczba parametrów funkcji z adnotacjami. |
Wskazuje, że funkcja z adnotacjami akceptuje zmienną liczbę parametrów, i określa typ parametrów zmiennych. |
Opcjonalny parametr w adnotacji @param
|
@param {number=} opt_argument Parametr opcjonalny typu number .
|
Wskazuje, że argument opisany przez adnotację
Jeśli wywołanie metody pomija parametr opcjonalny, argument ten będzie miał 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; } |
Argument opcjonalny w typie funkcji |
{function(?string=, number=)} Funkcja, która przyjmuje jako argumenty jeden opcjonalny ciąg znaków z możliwością wartości null i jedną opcjonalną liczbę. |
Wskazuje, że argument w typie funkcji jest opcjonalny. Argument opcjonalny można pominąć w wywołaniu funkcji. Argument opcjonalny nie może poprzedzać argumentu nieopcjonalnego na liście argumentów. |
Typ ALL | {*} |
Wskazuje, że zmienna może przyjmować dowolny typ. |
Typ UNKNOWN | {?} |
Wskazuje, że zmienna może mieć dowolny typ, a kompilator nie powinien sprawdzać typów w żadnym przypadku jej użycia. |
Rzutowanie typu
Aby przekształcić wartość w określony typ, użyj tej składni:
/** @type {!MyType} */ (valueExpression)
Typy generyczne
Podobnie jak Java, kompilator Closure obsługuje typy, funkcje i metody ogólne. Typy generyczne działają na obiektach różnych typów, zachowując bezpieczeństwo typów w czasie kompilacji.
Możesz używać typów ogólnych do implementowania uogólnionych kolekcji, które zawierają odwołania do obiektów określonego typu, oraz uogólnionych algorytmów, które działają na obiektach określonego typu.
Deklarowanie typu ogólnego
Typ można uogólnić, dodając adnotację @template
do konstruktora typu (w przypadku klas) lub deklaracji interfejsu (w przypadku interfejsów). Na przykład:
/** * @constructor * @template T */ Foo = function() { ... };
Adnotacja @template T
oznacza, że Foo
jest typem ogólnym z 1 typem szablonu, T
.
Typ szablonu T
może być używany jako typ w zakresie definicji Foo
. Na przykład:
/** @return {T} */ Foo.prototype.get = function() { ... }; /** @param {T} t */ Foo.prototype.set = function(t) { ... };
Metoda get
zwróci obiekt typu T
, a metoda set
zaakceptuje tylko obiekty typu T
.
Tworzenie instancji typu ogólnego
Korzystając z powyższego przykładu, instancję szablonu Foo
można utworzyć na kilka sposobów:
/** @type {!Foo<string>} */ var foo = new Foo(); var foo = /** @type {!Foo<string>} */ (new Foo());
Obie powyższe instrukcje konstruktora tworzą instancję Foo
, której typ szablonu T
to string
. Kompilator będzie wymuszać, aby wywołania metod foo
i dostęp do właściwości foo
były zgodne z typem szablonu. Na przykład:
foo.set("hello"); // OK. foo.set(3); // Error - expected a string, found a number. var x = foo.get(); // x is a string.
Typ instancji może być też określony niejawnie przez argumenty konstruktora.
Rozważ inny typ ogólny, 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 wnioskowany jako string
, a w rezultacie utworzona instancja bar
jest wnioskowana jako Bar<string>
.
Wiele typów szablonów
Szablon ogólny może mieć dowolną liczbę typów szablonów. Ta klasa mapy ma 2 typy szablonów:
/** * @constructor * @template Key, Val */ MyMap = function() { ... };
Wszystkie typy szablonów dla typu ogólnego muszą być określone w tym samym adnotacji @template
jako lista rozdzielona przecinkami. Kolejność nazw typów szablonów jest ważna, ponieważ adnotacje typu szablonu będą używać tej kolejności do łączenia typów szablonów z wartościami. Na przykład:
/** @type {MyMap<string, number>} */ var map; // Key = string, Val = number.
Niezmienność typów ogólnych
Kompilator Closure Compiler wymusza niezmienne typowanie ogólne. Oznacza to, że jeśli kontekst oczekuje typu Foo<X>
, nie możesz przekazać typu Foo<Y>
, gdy X
i Y
są różnymi typami, nawet jeśli jeden jest podtypem drugiego. Na 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 mogą być stałe lub propagowane do typu dziedziczącego. Oto przykład typu dziedziczącego, który poprawia typ szablonu swojego nadtypu:
/** * @constructor * @template T */ A = function() { ... }; /** @param {T} t */ A.prototype.method = function(t) { ... }; /** * @constructor * @extends {A<string>} */ B = function() { ... };
Rozszerzając klasę A<string>
, klasa B
będzie miała metodę method
, która przyjmuje parametr typu string
.
Oto przykład typu dziedziczonego, który propaguje typ szablonu swojego typu nadrzędnego:
/** * @constructor * @template U * @extends {A<U>} */ C = function() { ... };
Dzięki rozszerzeniu A<U>
instancje 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, ale pojedynczy typ nie może implementować tego samego interfejsu wiele razy z różnymi typami szablonów. Na 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 uczynić ogólnymi, dodając do ich definicji adnotację @template
. Na 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