Hinweis: Diese Seite ist veraltet. Die vollständige Liste finden Sie unter https://github.com/google/closure-composerr/wiki/Annotating-JavaScript-for-the-Closure-Compiler
Übersicht
Der Closure Compiler kann Datentypinformationen über JavaScript-Variablen verwenden, um eine optimierte Optimierung und Warnungen zu bieten. JavaScript kann Typen jedoch nicht deklarieren.
Da JavaScript keine Syntax zum Deklarieren des Variablentyps hat, müssen Sie Kommentare im Code verwenden, um den Datentyp anzugeben.
Die Sprache des Closure-Compilers beruht auf den Annotationen, die vom Tool zum Generieren von JSDoc-Dateien verwendet wurden. Er wurde jedoch inzwischen voneinander abgeleitet. Es enthält jetzt mehrere Anmerkungen, die JSDoc nicht unterstützt, und umgekehrt. In diesem Dokument werden die Annotationen und Typausdrücke beschrieben, die vom Closure Compiler verstanden werden.
JSDoc-Tags
Der Closure Compiler sucht in JSDoc-Tags nach Typinformationen. Verwenden Sie die in der Referenztabelle 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 Dokumentation zum JSDoc Toolkit.
Tag | Beschreibung |
---|---|
@abstract
|
Markiert 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
|
Kennzeichnet 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
|
Kennzeichnet eine Funktion als Konstruktor.
Der Compiler benötigt eine Beispiel: /** * A rectangle. * @constructor */ function GM_Rect() { ... } |
@define
|
Gibt eine Konstante an, die zum Zeitpunkt der Kompilierung vom Compiler überschrieben werden kann.
Mit dem Beispiel auf der linken Seite können Sie das Flag --define='ENABLE_DEBUG=false' an den Compiler übergeben, um den Wert von ENABLE_DEBUG zu false zu ändern.
Der Typ einer definierten Konstante kann eine Zahl, ein String oder ein boolescher Wert sein.
Definitionen sind nur im globalen Bereich zulässig.
Beispiel: /** @define {boolean} */ var ENABLE_DEBUG = true; /** @define {boolean} */ goog.userAgent.ASSUME_IE = false; |
@deprecated
|
Kennzeichnet eine Funktion, Methode oder Eigenschaft, sodass eine Compiler-Warnung angezeigt wird, die besagt, 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
|
Mit 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 Aufzählung an. Ein Enum ist ein Objekt, dessen Attribute eine Gruppe verwandter Konstanten ergeben. Auf das Das Typlabel einer Aufzählung gilt für jedes Attribut der Aufzählung. Wenn eine Aufzählung beispielsweise den Typ Beispiel: /** * Enum for tri-state values. * @enum {number} */ project.TriState = { TRUE: 1, FALSE: -1, MAYBE: 0 }; |
@export
|
Mit diesem 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 unkompilierten Code exportiert. Sie können /** * @export * @type {SomeType} */schreiben Code, der die Annotation
|
@extends
|
Kennzeichnet eine Klasse oder Schnittstelle als von einer anderen Klasse übernommen. Eine mit
Hinweis:
Ein Beispiel für die Implementierung der Übernahme finden Sie unter Funktion „Closure Library“ 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 kann. 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 angezeigt werden.
Die Eigenschaft hat einen deklarierten Typ, aber Sie können ihr einen beliebigen Typ ohne Warnung 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 abgeleiteten Klasse absichtlich eine Methode oder Eigenschaft der übergeordneten Klasse verbirgt und genau dieselbe Dokumentation hat. Das Tag Beispiel: /** @inheritDoc */ project.SubClass.prototype.toString = function() { ... }; |
@interface
|
Kennzeichnet eine Funktion als Schnittstelle. Eine Schnittstelle gibt die erforderlichen Mitglieder eines Typs an. Jede Klasse, die eine Schnittstelle implementiert, muss alle Methoden und Attribute implementieren, die auf dem Prototyp der Schnittstelle definiert sind. Weitere Informationen finden Sie unter
Der Compiler überprüft, ob Schnittstellen nicht instanziiert sind. 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 Annotation sollte nur für Objektliterale angezeigt werden.
Beachten Sie, dass der Name in geschweiften Klammern kein Typname wie in anderen Annotationen ist. Es ist ein Objektname. Sie benennt das Objekt, an das die Properties gemietet werden.
Weitere Informationen zu dieser Annotation finden Sie in den JSDoc Toolkit-Dokumenten. 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 Annotation können wichtige Hinweise wie rechtliche Lizenzen oder Urheberrechtstexte weiterhin kompiliert 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 eine Variable minimiert werden soll. Der primäre Zweck von 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 Nebeneffekte hat.
Mit dieser Annotation kann der Compiler Aufrufe an die Funktion entfernen, wenn der Rückgabewert nicht verwendet wird. Die Annotation 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 abgeleiteten Klasse absichtlich eine Methode oder Eigenschaft der übergeordneten Klasse ausgeblendet. Wenn keine anderen Annotationen enthalten sind, übernimmt die Methode oder Property automatisch Annotationen von der übergeordneten Klasse. Beispiel: /** * @return {string} Human-readable representation of * project.SubClass. * @override */ project.SubClass.prototype.toString = function() { ... }; |
@package
|
Kennzeichnet ein Mitglied oder eine Property als privat. Nur Code im selben Verzeichnis kann auf Namen zugreifen, die als
Öffentliche Konstruktoren können Attribute vom Typ 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 zum Angeben der Arten von Funktionsargumenten verwendet.
Auf das Tag
Alternativ können Sie die Parametertypen inline annotieren (siehe Beispiel 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; }Für Parameter, die ein destruktives Muster haben, können Sie nach der Typannotation einen beliebigen Namen verwenden, der eine gültige JS-ID ist. /** * @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 als
Auf die öffentlichen statischen Attribute von als Beispiel: /** * Handlers that are listening to this logger. * @private {Array<Function>} */ this.handlers_ = []; |
@protected
|
Gibt an, dass ein Mitglied oder eine Property geschützt ist.
Eine Property mit dem Label
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
|
Kennzeichnet eine Funktion als Strukturschnittstelle. Eine Strukturschnittstelle ähnelt einer nominalen 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 Tag
Alternativ können Sie den Rückgabetyp inline angeben (siehe Beispiel
Wenn eine Funktion, die nicht in extern enthalten ist, keinen Rückgabewert hat, können Sie das Tag 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
|
Mit 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
|
Siehe Allgemeine Typen. Beispiel: /** * @param {T} t * @constructor * @template T */ Container = function(t) { ... }; |
@this
|
Gibt den Objekttyp an, auf den das Keyword
Um Compiler-Warnungen zu vermeiden, müssen Sie die Annotation 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. Die Typprüfung verwendet diese Informationen derzeit nicht. Sie wird nur verwendet, um herauszufinden, ob eine in einer externen Datei deklarierte Funktion Nebeneffekte hat. Beispiel: /** * @throws {DOMException} */ DOMApplicationCache.prototype.swapCache = function() { ... }; |
@type
|
Gibt den Typ einer Variablen, eines Attributs oder eines Ausdrucks an. Auf das Tag Wenn Sie eine Variable oder einen Funktionsparameter deklarieren, können Sie die Typannotation wie im zweiten Beispiel inline weglassen und dabei Beispiel: /** * The message hex ID. * @type {string} */ var hexId = hexId; var /** string */ name = 'Jamie'; function useSomething(/** (string|number|!Object) */ something) { ... } |
@typedef
|
Gibt einen Alias für einen komplexeren Typ an. Derzeit können typedef-Elemente nur auf der obersten Ebene, nicht innerhalb von Funktionen, definiert werden. Wir haben diese Einschränkung in der neuen Inferenztyp 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
Sie können den Datentyp einer beliebigen Variablen, Eigenschaft, eines Ausdrucks oder Funktionsparameters mit einem Typausdruck 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, eines Attributs oder eines Ausdrucks zu deklarieren.
Je mehr Typen Sie im Code angeben, desto mehr Optimierungen kann der Compiler ausführen und desto mehr Fehler können erkannt werden.
Der Compiler verwendet diese Annotationen zur Typprüfung Ihres Programms.
Beachten Sie, dass der Closure Compiler keine Zusicherungen macht, dass er in der Lage ist, die Art jedes Ausdrucks in Ihrem Programm zu ermitteln. Er analysiert, wie Variablen verwendet werden und welche Annotationen mit den jeweiligen Deklarationen verknüpft sind. Dann wird eine Reihe von Algorithmen für Typinferenzen verwendet, um so viele Ausdrücke wie möglich zu ermitteln. Einige dieser Algorithmen sind unkompliziert („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. In diesem Fall muss f(function(x) { /** ... */ });
eine Zahl sein.
Name des Operators | Syntaxbeispiele | Beschreibung |
---|---|---|
Typname |
{boolean} {Window} {goog.ui.Menu}
|
Gibt den Namen eines Typs an. |
Art der Anwendung |
{Array<string>} Ein String-Array.
|
Parametrisiert einen Typ mit einer Reihe von Typargumenten. Ähnlich wie Java-Generika. |
Typ „Union“ |
{(number|boolean)} Eine Zahl oder ein boolescher Wert. Notieren Sie die erforderlichen Klammern. |
Gibt an, dass ein Wert vom Typ A ODER vom Typ B sein kann. |
Datensatztyp |
{{myNum: number, myObject}}
Ein anonymer Typ mit einer Property namens myNum , die einen Wert vom Typ number hat, und einer Property namens myObject , die einen Wert eines beliebigen Typs hat.
|
Gibt an, dass der Wert die angegebenen Mitglieder mit Werten der angegebenen Typen hat. Klammern sind Teil der Typsyntax. Zum Beispiel könnten Sie ein Objekt vom Typ |
Typ „Nullwerte zulässig“ |
{?number} Eine Zahl oder null .
|
Gibt an, dass ein Wert vom Typ A oder Alle Objekttypen sind standardmäßig für Nullwerte zulässig, unabhängig davon, ob sie mit dem Nullable-Operator deklariert wurden. Ein Objekttyp ist alles, außer eine Funktion, ein String, eine Zahl oder ein boolescher Wert. Verwenden Sie den Operator Non-nullable, um einen Objekttyp zu konfigurieren, der keine Nullwerte zulässt. |
Typ, der keine Nullwerte zulässt |
{!Object} Ein Objekt, aber niemals 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 null. Dies gilt unabhängig davon, ob sie mit dem Operator, der keine Nullwerte zulässig ist, deklariert wird. Verwenden Sie den Operator Nullable, um einen Wert oder einen Funktionstyp für Nullwerte zulässig zu machen. |
Funktionstyp |
{function(string, boolean)} Eine Funktion, die zwei Parameter (einen String und einen booleschen Wert) mit einem unbekannten Rückgabewert verwendet. |
Gibt eine Funktion und die Typen der Funktionsparameter an. |
Rückgabetyp der Funktion |
{function(): number} Eine Funktion, die keine Parameter annimmt und eine Zahl zurückgibt. |
Gibt den Typ des Rückgabewerts einer Funktion an. |
Typ der Funktion this |
{function(this:goog.ui.Menu, string)} Eine Funktion, die einen Parameter (String) annimmt und im Kontext eines goog.ui.Menu ausführt. |
Gibt den Typ des Werts this in der Funktion an. |
Typ der Funktion new |
{function(new:goog.ui.Menu, string)} Eine Funktion, die einen Parameter (String) verwendet und eine neue Instanz von goog.ui.Menu erstellt, wenn sie mit dem Schlüsselwort „new“ aufgerufen wird. |
Gibt den konstruierten Typ eines Konstruktors an. |
Variablenparameter |
{function(string, ...number): number} Eine Funktion, die einen Parameter (String) und dann eine variable Anzahl von Parametern verwendet, die Zahlen sein müssen. |
Gibt an, dass ein Funktionstyp eine variable Anzahl von Parametern und einen Typ für die variablen Parameter angibt. |
Variablenparameter (in @param -Annotationen)
|
@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 einen Typ für die variablen Parameter angibt. |
Optionaler Parameter in einer @param -Annotation
|
@param {number=} opt_argument Ein optionaler Parameter vom Typ number .
|
Gibt an, dass das durch eine
Wenn ein Methodenaufruf einen optionalen Parameter auslässt, hat dieses 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 String mit Nullwert und eine optionale Zahl als Argumente akzeptiert. |
Gibt an, dass ein Argument in einem Funktionstyp optional ist. Ein optionales Argument kann im Funktionsaufruf weggelassen werden. Ein optionales Argument kann einem nicht optionalen Argument in der Argumentliste nicht vorangestellt werden. |
Typ ALL | {*} |
Gibt an, dass die Variable einen beliebigen Typ annehmen kann. |
Typ UNKNOWN | {?} |
Gibt an, dass die Variable einen beliebigen Typ annehmen kann und der Compiler keine Verwendung dafür prüfen sollte. |
Typumwandlung
Verwenden Sie diese Syntax, um einen Wert in einen bestimmten Typ umzuwandeln.
/** @type {!MyType} */ (valueExpression)Die Klammern rund um den Ausdruck sind immer erforderlich.
Generische Typen
Ähnlich wie Java unterstützt der Closure Compiler allgemeine Typen, Funktionen und Methoden. Generische arbeiten mit Objekten verschiedener Typen, während die Sicherheit beim Kompilierungszeittyp erhalten bleibt.
Mit generischen Sammlungen lassen sich allgemeine Sammlungen implementieren, die Verweise auf Objekte eines bestimmten Typs enthalten, sowie allgemeine Algorithmen, die Objekte eines bestimmten Typs verarbeiten.
Generischen Typ angeben
Ein Typ kann als generische Annotation definiert werden, indem dem Konstruktor des Typs eine @template
-Annotation (für Klassen) oder einer Schnittstellendeklaration (für Schnittstellen) hinzugefügt wird. Beispiel:
/** * @constructor * @template T */ Foo = function() { ... };
Die Annotation @template T
gibt an, dass Foo
ein generischer Typ mit einem Vorlagentyp ist, T
.
Der Vorlagentyp T
kann als Typ im Bereich 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 vom Typ T
zurück und die Methode set
akzeptiert nur Objekte vom Typ T
.
Instanziierung eines generischen Typs
Für das obige Beispiel 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 der obigen Konstruktoranweisungen wird eine Foo
-Instanz erstellt, deren Vorlagentyp T
string
ist. Der Compiler erzwingt, dass die Methoden von foo
aufgerufen werden und der Zugriff auf die Attribute von foo
erfolgt, wobei der Vorlagentyp berücksichtigt wird. 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 eingegeben werden.
Ein anderer generischer Typ ist 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 Bar
-Konstruktor wird als string
abgeleitet. Deshalb wird die erstellte Instanz bar
als Bar<string>
abgeleitet.
Mehrere Vorlagentypen
Ein generischer Typ kann eine beliebige Anzahl von 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 Anmerkungen aus Vorlagentypen die Sortierung verwenden, um Vorlagentypen mit den Werten zu koppeln. Beispiel:
/** @type {MyMap<string, number>} */ var map; // Key = string, Val = number.
Varianz generischer Typen
Der Closure Compiler erzwingt eine unveränderliche generische Eingabe. Wenn ein Kontext also den Typ Foo<X>
erwartet, können Sie einen Typ Foo<Y>
nicht übergeben, wenn X
und Y
unterschiedliche Typen sind, auch wenn einer der beiden Untertypen 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
Übernahme generischer Typen
Generische Typen können übernommen werden und ihre Vorlagentypen können entweder festgelegt oder an den übernommenen Typ weitergegeben werden. Hier ist ein Beispiel für einen übernommenen Typ, der den Vorlagentyp seines Supertyps 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>
erhält B
die Methode method
, die einen Parameter vom Typ string
annimmt.
Hier ist ein Beispiel für einen Übernahmetyp, der den Vorlagentyp seines Supertyps übergibt:
/** * @constructor * @template U * @extends {A<U>} */ C = function() { ... };
Durch die Erweiterung von A<U>
haben Vorlageninstanzen von C
die Methode method
, die einen Parameter des Vorlagentyps U
verwendet.
Schnittstellen können auf ähnliche Weise implementiert und erweitert werden, allerdings kann ein einzelner Typ dieselbe Schnittstelle nicht mehrfach mit unterschiedlichen 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
Allgemeine Funktionen und Methoden
Ähnlich wie allgemeine Typen können Funktionen und Methoden auch generisch gestaltet werden, indem Sie der Definition eine @template
-Annotation hinzufügen. 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