Hinweis: Diese Seite ist veraltet. Die vollständige Liste finden Sie unter https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler .
Übersicht
Der Closure Compiler kann Datentypinformationen zu JavaScript-Variablen verwenden, um die Optimierung und Warnungen zu verbessern. In JavaScript gibt es jedoch keine Möglichkeit, Typen zu deklarieren.
Da es in JavaScript keine Syntax zum Deklarieren des Typs einer Variablen gibt, müssen Sie Kommentare im Code verwenden, um den Datentyp anzugeben.
Die Typsprache des Closure Compilers leitet sich von den Anmerkungen ab, die vom Tool zur Dokumentgenerierung JSDoc verwendet werden. Sie hat sich jedoch inzwischen weiterentwickelt. Es enthält jetzt mehrere Annotationen, die JSDoc nicht unterstützt, und umgekehrt. In diesem Dokument werden die Anmerkungen und Typausdrücke beschrieben, die der Closure Compiler versteht.
JSDoc-Tags
Der Closure Compiler sucht nach Typinformationen in JSDoc-Tags. Verwenden Sie die in der Referenztabelle unten beschriebenen JSDoc-Tags, damit der Compiler Ihren Code optimieren und auf mögliche Typfehler und andere Fehler prüfen kann.
Diese Tabelle enthält nur Tags, die sich auf das Verhalten des Closure Compilers auswirken. Informationen zu anderen JSDoc-Tags finden Sie in der JSDoc Toolkit-Dokumentation.
Tag | Beschreibung |
---|---|
@abstract
|
Kennzeichnet eine Methode als abstrakt. Ähnlich wie beim Festlegen einer Methode auf
Der Compiler gibt eine Warnung aus, wenn eine mit /** @abstract */ foo.MyClass.prototype.abstractMethod = function() {}; |
@const
|
Markiert eine Variable als schreibgeschützt. Der Compiler kann Die Typdeklaration ist optional.
Der Compiler gibt eine Warnung aus, wenn einer mit /** @const */ var MY_BEER = 'stout'; /** * My namespace's favorite kind of beer. * @const {string} */ mynamespace.MY_BEER = 'stout'; /** @const */ MyClass.MY_BEER = 'stout'; |
@constructor
|
Markiert eine Funktion als Konstruktor.
Der Compiler erfordert eine Beispiel: /** * A rectangle. * @constructor */ function GM_Rect() { ... } |
@define
|
Gibt eine Konstante an, die vom Compiler zur Kompilierzeit überschrieben werden kann.
Im Beispiel auf der linken Seite können Sie das Flag --define='ENABLE_DEBUG=false' an den Compiler übergeben, um den Wert von ENABLE_DEBUG in false zu ändern.
Der Typ einer definierten Konstanten kann „number“, „string“ oder „boolean“ sein.
Defines sind nur im globalen Bereich zulässig.
Beispiel: /** @define {boolean} */ var ENABLE_DEBUG = true; /** @define {boolean} */ goog.userAgent.ASSUME_IE = false; |
@deprecated
|
Markiert eine Funktion, Methode oder Eigenschaft, sodass bei der Verwendung eine Compilerwarnung ausgegeben wird, die darauf hinweist, dass sie nicht mehr verwendet werden sollte. Beispiel: /** * 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
|
Beispiel: /** * @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
|
Gibt den Typ einer Enumeration an. Ein Enum ist ein Objekt, dessen Eigenschaften eine Reihe verwandter Konstanten bilden. Auf das Das Typ-Label eines Enums gilt für jede Property des Enums. Wenn ein Enum beispielsweise den Typ Beispiel: /** * Enum for tri-state values. * @enum {number} */ project.TriState = { TRUE: 1, FALSE: -1, MAYBE: 0 }; |
@export
|
Angenommen, Sie haben diesen Code: /** @export */ foo.MyPublicClass.prototype.myPublicMethod = function() { // ... };
Wenn der Compiler mit dem Flag goog.exportProperty(foo.MyPublicClass.prototype, 'myPublicMethod', foo.MyPublicClass.prototype.myPublicMethod); Dadurch werden die Symbole in nicht kompilierten Code exportiert. Sie können /** * @export * @type {SomeType} */ Code, der die Annotation
|
@extends
|
Markiert eine Klasse oder Schnittstelle als von einer anderen Klasse abgeleitet. Eine mit
Hinweis:
Ein Beispiel für die Implementierung der Vererbung finden Sie in der Closure-Bibliotheksfunktion Beispiel: /** * Immutable empty node list. * @constructor * @extends {goog.ds.BasicNodeList} */ goog.ds.EmptyNodeList = function() { ... }; |
@final
|
Gibt an, dass diese Klasse nicht erweitert werden darf. Gibt für Methoden an, dass keine Unterklasse diese Methode überschreiben darf. Beispiel: /** * A class that cannot be extended. * @final * @constructor */ sloth.MyFinalClass = function() { ... } /** * A method that cannot be overridden. * @final */ sloth.MyFinalClass.prototype.method = function() { ... }; |
@implements
|
Wird mit
Der Compiler gibt eine Warnung aus, wenn Sie einen Konstruktor mit Beispiel: /** * A shape. * @interface */ function Shape() {}; Shape.prototype.draw = function() {}; /** * @constructor * @implements {Shape} */ function Square() {}; Square.prototype.draw = function() { ... }; |
@implicitCast
|
Diese Annotation kann nur in externen Property-Deklarationen verwendet werden.
Für die Eigenschaft ist ein Typ deklariert, Sie können ihr jedoch ohne Warnung einen beliebigen Typ zuweisen. Beim Zugriff auf die Property wird ein Wert des deklarierten Typs zurückgegeben. /** * @type {string} * @implicitCast */ Element.prototype.innerHTML; |
@inheritDoc
|
Gibt an, dass eine Methode oder Eigenschaft einer Unterklasse absichtlich eine Methode oder Eigenschaft der Superklasse verbirgt und genau dieselbe Dokumentation hat. Das Tag Beispiel: /** @inheritDoc */ project.SubClass.prototype.toString = function() { ... }; |
@interface
|
Markiert eine Funktion als Schnittstelle. Eine Schnittstelle gibt die erforderlichen Member eines Typs an. Jede Klasse, die eine Schnittstelle implementiert, muss alle Methoden und Eigenschaften implementieren, die im Prototyp der Schnittstelle definiert sind. Weitere Informationen finden Sie unter
Der Compiler prüft, ob Schnittstellen instanziiert werden. Wenn das Schlüsselwort Beispiel: /** * A shape. * @interface */ function Shape() {}; Shape.prototype.draw = function() {}; /** * A polygon. * @interface * @extends {Shape} */ function Polygon() {}; Polygon.prototype.getSides = function() {}; |
@lends
|
Gibt an, dass die Schlüssel eines Objektliterals als Attribute eines anderen Objekts behandelt werden sollen. Diese Anmerkung sollte nur für Objektliterale verwendet werden.
Der Name in geschweiften Klammern ist kein Typname wie in anderen Anmerkungen. Es ist ein Objektname. Es gibt den Namen des Objekts an, dem die Eigenschaften geliehen werden.
Beispiel: Weitere Informationen zu dieser Annotation finden Sie in der JSDoc Toolkit-Dokumentation. Beispiel: goog.object.extend( Button.prototype, /** @lends {Button.prototype} */ ({ isButton: function() { return true; } })); |
@license oder @preserve
|
Weist den Compiler an, den zugehörigen Kommentar vor dem kompilierten Code für die markierte Datei einzufügen. Mit dieser Anmerkung können wichtige Hinweise (z. B. rechtliche Lizenzen oder Urheberrechtstext) unverändert in die Kompilierung übernommen werden. Zeilenumbrüche werden beibehalten. Beispiel: /** * @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
|
Gibt ein Attribut an, das vom Compiler nicht in einer Variablen zusammengefasst werden soll. Beispiel: /** * A namespace. * @const */ var foo = {}; /** * @nocollapse */ foo.bar = 42; window['foobar'] = foo.bar; |
@nosideeffects
|
Gibt an, dass ein Aufruf der deklarierten externen Funktion keine Nebenwirkungen hat.
Mit dieser Anmerkung kann der Compiler Aufrufe der Funktion entfernen, wenn der Rückgabewert nicht verwendet wird. Die Anmerkung ist nur in Beispiel: /** @nosideeffects */ function noSideEffectsFn1() {} /** @nosideeffects */ var noSideEffectsFn2 = function() {}; /** @nosideeffects */ a.prototype.noSideEffectsFn3 = function() {}; |
@override
|
Gibt an, dass eine Methode oder Eigenschaft einer Unterklasse absichtlich eine Methode oder Eigenschaft der Superklasse ausblendet. Wenn keine anderen Annotationen enthalten sind, erbt die Methode oder das Attribut automatisch Annotationen von der zugehörigen Superklasse. Beispiel: /** * @return {string} Human-readable representation of * project.SubClass. * @override */ project.SubClass.prototype.toString = function() { ... }; |
@package
|
Kennzeichnet ein Mitglied oder eine Eigenschaft als „package private“. Nur Code im selben Verzeichnis kann auf Namen zugreifen, die mit
Öffentliche Konstruktoren können Beispiel: /** * 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
|
Wird mit Methoden-, Funktions- und Konstruktordefinitionen verwendet, um die Typen von Funktionsargumenten anzugeben.
Auf das
Alternativ können Sie die Typen der Parameter auch inline angeben (siehe Funktion Beispiel: /** * 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
|
Kennzeichnet ein Mitglied als privat. Nur Code in derselben Datei kann auf globale Variablen und Funktionen zugreifen, die mit
Auf die öffentlichen statischen Eigenschaften von Konstruktoren, die mit Beispiel: /** * Handlers that are listening to this logger. * @private {Array<Function>} */ this.handlers_ = []; |
@protected
|
Gibt an, dass ein Mitglied oder eine Eigenschaft geschützt ist.
Eine mit
Beispiel: /** * 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
|
Markiert eine Funktion als strukturelle Schnittstelle. Eine strukturelle Schnittstelle ähnelt einer nominellen Beispiel: /** * 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
|
Gibt die Rückgabetypen von Methoden- und Funktionsdefinitionen an.
Auf das
Alternativ können Sie den Rückgabetyp inline annotieren (siehe Funktion
Wenn eine Funktion, die nicht in Externs enthalten ist, keinen Rückgabewert hat, können Sie das Beispiel: /** * 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
|
Beispiel: /** * @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
|
Weitere Informationen finden Sie unter Generische Typen. Beispiel: /** * @param {T} t * @constructor * @template T */ Container = function(t) { ... }; |
@this
|
Gibt den Typ des Objekts an, auf das sich das Schlüsselwort
Um Compilerwarnungen zu vermeiden, müssen Sie immer dann eine Beispiel: chat.RosterWidget.extern('getRosterElement', /** * Returns the roster widget element. * @this {Widget} * @return {Element} */ function() { return this.getComponent().getElement(); }); |
@throws
|
Wird verwendet, um die von einer Funktion ausgelösten Ausnahmen zu dokumentieren. Derzeit werden diese Informationen nicht vom Type Checker verwendet. Sie wird nur verwendet, um festzustellen, ob eine in einer Externs-Datei deklarierte Funktion Nebeneffekte hat. Beispiel: /** * @throws {DOMException} */ DOMApplicationCache.prototype.swapCache = function() { ... }; |
@type
|
Gibt den Typ einer Variablen, Eigenschaft oder eines Ausdrucks an. Auf das Wenn Sie eine Variable oder einen Funktionsparameter deklarieren, können Sie die Typanmerkung inline schreiben und dabei Beispiel: /** * The message hex ID. * @type {string} */ var hexId = hexId; var /** string */ name = 'Jamie'; function useSomething(/** (string|number|!Object) */ something) { ... } |
@typedef
|
Deklariert einen Alias für einen komplexeren Typ. Derzeit können Typdefinitionen nur auf der obersten Ebene und nicht innerhalb von Funktionen definiert werden. Wir haben diese Einschränkung in der neuen Typinferenz behoben. Beispiel: /** @typedef {(string|number)} */ goog.NumberLike; /** @param {goog.NumberLike} x A number or a string. */ goog.readNumber = function(x) { ... } |
@unrestricted
|
Gibt an, dass eine Klasse weder vom Typ Beispiel: /** * @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 |
Typausdrücke
Mit einem Typausdruck können Sie den Datentyp einer beliebigen Variablen, Eigenschaft, eines beliebigen Ausdrucks oder Funktionsparameters angeben. Ein Typausdruck besteht aus geschweiften Klammern („{ }“), die eine Kombination der unten beschriebenen Typoperatoren enthalten.
Verwenden Sie einen Typausdruck mit dem Tag @param
, um den Typ eines Funktionsparameters zu deklarieren. Verwenden Sie einen Typausdruck mit dem Tag @type
, um den Typ einer Variablen, Eigenschaft oder eines Ausdrucks zu deklarieren.
Je mehr Typen Sie in Ihrem Code angeben, desto mehr Optimierungen kann der Compiler vornehmen und desto mehr Fehler kann er erkennen.
Der Compiler verwendet diese Anmerkungen, um Ihr Programm auf Typen zu prüfen.
Der Closure Compiler kann nicht garantieren, dass er den Typ jedes Ausdrucks in Ihrem Programm ermitteln kann. Es wird versucht, die Verwendung von Variablen und die Typanmerkungen in ihren Deklarationen zu analysieren. Anschließend werden eine Reihe von Algorithmen zur Typinferenz verwendet, um den Typ möglichst vieler Ausdrücke zu ermitteln. Einige dieser Algorithmen sind einfach („Wenn x eine Zahl ist und wir y = x;
sehen, dann ist y eine Zahl“). Einige sind indirekter („Wenn der erste Parameter von f als Callback dokumentiert ist, der eine Zahl annehmen muss, und wir f(function(x) { /** ... */ });
sehen, dann muss x eine Zahl sein“).
Name des Operators | Syntaxbeispiele | Beschreibung |
---|---|---|
Typname |
{boolean} {Window} {goog.ui.Menu}
|
Gibt den Namen eines Typs an. |
App-Typ |
{Array<string>} Ein Array von Strings.
|
Parametrisiert einen Typ mit einer Reihe von Typargumenten. Ähnlich wie Java-Generics. |
Typ „Union“ |
{(number|boolean)} Eine Zahl oder ein boolescher Wert. Beachten Sie die erforderlichen Klammern. |
Gibt an, dass ein Wert entweder Typ A oder Typ B haben kann. |
Datensatztyp |
{{myNum: number, myObject}}
Ein anonymer Typ mit einem Attribut namens myNum , das einen Wert vom Typ number hat, und einem Attribut namens myObject , das einen Wert eines beliebigen Typs hat.
|
Gibt an, dass der Wert die angegebenen Elemente mit Werten der angegebenen Typen hat. Geschweifte Klammern sind Teil der Typsyntax. Um beispielsweise eine |
Typ mit zulässigen Nullwerten |
{?number} Eine Zahl oder null .
|
Gibt an, dass ein Wert vom Typ A oder Alle Objekttypen sind standardmäßig nullable, unabhängig davon, ob sie mit dem Operator „Nullable“ deklariert werden. Ein Objekttyp ist alles außer einer Funktion, einem String, einer Zahl oder einem booleschen Wert. Verwenden Sie den Operator Non-nullable, um einen Objekttyp als nicht nullfähig festzulegen. |
Nicht nullable-Typ |
{!Object} Ein Objekt, aber nie der Wert null .
|
Gibt an, dass ein Wert vom Typ A und nicht null ist. Funktionen und alle Werttypen (boolesch, Zahl und String) sind standardmäßig nicht nullable, unabhängig davon, ob sie mit dem Operator „Non-nullable“ deklariert werden. Verwenden Sie den Operator Nullable, um einen Wert oder Funktionstyp als „nullable“ festzulegen. |
Funktionstyp |
{function(string, boolean)} Eine Funktion, die zwei Parameter (einen String und einen booleschen Wert) verwendet und einen unbekannten Rückgabewert hat. |
Gibt eine Funktion und die Typen der Parameter der Funktion an. |
Rückgabetyp der Funktion |
{function(): number} Eine Funktion, die keine Parameter verwendet und eine Zahl zurückgibt. |
Gibt den Typ des Rückgabewerts einer Funktion an. |
Funktion this Typ |
{function(this:goog.ui.Menu, string)} Eine Funktion, die einen Parameter (einen String) verwendet und im Kontext von goog.ui.Menu ausgeführt wird. |
Gibt den Typ des Werts von this innerhalb der Funktion an. |
Funktion new Typ |
{function(new:goog.ui.Menu, string)} Eine Funktion, die einen Parameter (einen String) akzeptiert und eine neue Instanz von goog.ui.Menu erstellt, wenn sie mit dem Keyword „new“ aufgerufen wird. |
Gibt den konstruierten Typ eines Konstruktors an. |
Variable Parameter |
{function(string, ...number): number} Eine Funktion, die einen Parameter (einen String) und dann eine variable Anzahl von Parametern verwendet, die Zahlen sein müssen. |
Gibt an, dass ein Funktionstyp eine variable Anzahl von Parametern akzeptiert, und gibt einen Typ für die variablen Parameter an. |
Variablenparameter (in @param -Hinweisen)
|
@param {...number} var_args Eine variable Anzahl von Parametern für eine annotierte Funktion. |
Gibt an, dass die annotierte Funktion eine variable Anzahl von Parametern akzeptiert, und gibt einen Typ für die variablen Parameter an. |
Optionaler Parameter in einer @param -Anmerkung
|
@param {number=} opt_argument Ein optionaler Parameter vom Typ number .
|
Gibt an, dass das durch eine
Wenn bei einem Methodenaufruf ein optionaler Parameter ausgelassen wird, hat das Argument den Wert /** * 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; } |
Optionales Argument in einem Funktionstyp |
{function(?string=, number=)} Eine Funktion, die einen optionalen, auf null setzbaren String und eine optionale Zahl als Argumente akzeptiert. |
Gibt an, dass ein Argument in einem Funktionstyp optional ist. Ein optionales Argument kann beim Funktionsaufruf weggelassen werden. Ein optionales Argument darf in der Argumentliste nicht vor einem nicht optionalen Argument stehen. |
Der Typ „ALL“ | {*} |
Gibt an, dass die Variable einen beliebigen Typ annehmen kann. |
Der Typ „UNKNOWN“ | {?} |
Gibt an, dass die Variable einen beliebigen Typ annehmen kann und der Compiler keine Typüberprüfung für die Verwendung der Variablen durchführen soll. |
Typumwandlung
Verwenden Sie die folgende Syntax, um einen Wert in einen bestimmten Typ umzuwandeln:
/** @type {!MyType} */ (valueExpression)
Generische Typen
Ähnlich wie Java unterstützt der Closure Compiler generische Typen, Funktionen und Methoden. Generics arbeiten mit Objekten verschiedener Typen und bewahren gleichzeitig die Typsicherheit zur Kompilierzeit.
Sie können Generics verwenden, um verallgemeinerte Sammlungen zu implementieren, die Verweise auf Objekte eines bestimmten Typs enthalten, und verallgemeinerte Algorithmen, die für Objekte eines bestimmten Typs ausgeführt werden.
Generischen Typ deklarieren
Ein Typ kann generisch gemacht werden, indem dem Konstruktor des Typs (für Klassen) oder der Schnittstellendeklaration (für Schnittstellen) eine @template
-Annotation hinzugefügt wird. Beispiel:
/** * @constructor * @template T */ Foo = function() { ... };
Die Annotation @template T
gibt an, dass Foo
ein generischer Typ mit einem Vorlagentyp, T
, ist.
Der Vorlagentyp T
kann als Typ im Rahmen der Definition von Foo
verwendet werden. Beispiel:
/** @return {T} */ Foo.prototype.get = function() { ... }; /** @param {T} t */ Foo.prototype.set = function(t) { ... };
Die Methode get
gibt ein Objekt des Typs T
zurück und die Methode set
akzeptiert nur Objekte des Typs T
.
Generischen Typ instanziieren
Wenn wir das obige Beispiel wiederverwenden, kann eine Vorlageninstanz von Foo
auf verschiedene Arten erstellt werden:
/** @type {!Foo<string>} */ var foo = new Foo(); var foo = /** @type {!Foo<string>} */ (new Foo());
Mit beiden oben genannten Konstruktoranweisungen wird eine Foo
-Instanz erstellt, deren Vorlagentyp T
string
ist. Der Compiler erzwingt, dass Aufrufe der Methoden von foo
und Zugriffe auf die Eigenschaften von foo
den Typ der Vorlage berücksichtigen. Beispiel:
foo.set("hello"); // OK. foo.set(3); // Error - expected a string, found a number. var x = foo.get(); // x is a string.
Instanzen können auch implizit durch ihre Konstruktorargumente typisiert werden.
Sehen Sie sich einen anderen generischen Typ an: Bar
/** * @param {T} t * @constructor * @template T */ Bar = function(t) { ... }; var bar = new Bar("hello"); // bar is a Bar<string>
Der Typ des Arguments für den Konstruktor Bar
wird als string
abgeleitet. Daher wird die erstellte Instanz bar
als Bar<string>
abgeleitet.
Mehrere Vorlagentypen
Ein generischer Typ kann beliebig viele Vorlagentypen haben. Die folgende Kartenklasse hat zwei Vorlagentypen:
/** * @constructor * @template Key, Val */ MyMap = function() { ... };
Alle Vorlagentypen für einen generischen Typ müssen in derselben @template
-Annotation als durch Kommas getrennte Liste angegeben werden. Die Reihenfolge der Namen der Vorlagentypen ist wichtig, da bei Anmerkungen für Vorlagentypen die Reihenfolge verwendet wird, um Vorlagentypen mit den Werten zu verknüpfen. Beispiel:
/** @type {MyMap<string, number>} */ var map; // Key = string, Val = number.
Invarianz generischer Typen
Der Closure Compiler erzwingt die invariante generische Typisierung. Wenn in einem Kontext der Typ Foo<X>
erwartet wird, können Sie also nicht den Typ Foo<Y>
übergeben, wenn X
und Y
unterschiedliche Typen sind, auch wenn einer ein Untertyp des anderen ist. Beispiel:
/** * @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
Vererbung generischer Typen
Generische Typen können übernommen werden und ihre Vorlagentypen können entweder festgelegt oder an den übernehmenden Typ weitergegeben werden. Hier ein Beispiel für einen untergeordneten Typ, der den Vorlagentyp seines übergeordneten Typs korrigiert:
/** * @constructor * @template T */ A = function() { ... }; /** @param {T} t */ A.prototype.method = function(t) { ... }; /** * @constructor * @extends {A<string>} */ B = function() { ... };
Durch die Erweiterung von A<string>
hat B
eine Methode method
, die einen Parameter vom Typ string
akzeptiert.
Hier sehen Sie ein Beispiel für einen untergeordneten Typ, der den Vorlagentyp seines übergeordneten Typs weitergibt:
/** * @constructor * @template U * @extends {A<U>} */ C = function() { ... };
Durch die Erweiterung von A<U>
haben Vorlageninstanzen von C
eine Methode method
, die einen Parameter des Vorlagentyps U
akzeptiert.
Schnittstellen können auf ähnliche Weise implementiert und erweitert werden, aber ein einzelner Typ kann dieselbe Schnittstelle nicht mehrmals mit verschiedenen Vorlagentypen implementieren. Beispiel:
/** * @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
Generische Funktionen und Methoden
Ähnlich wie bei generischen Typen können Funktionen und Methoden durch Hinzufügen einer @template
-Annotation zu ihrer Definition generisch gemacht werden. Beispiel:
/** * @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