JavaScript für den Closure Compiler annotieren

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.

  1. JSDoc-Tags
  2. Typausdrücke
  3. Allgemeine Typen

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 goog.abstractMethod kann der Compiler Methoden entfernen, die mit @abstract gekennzeichnet sind, um die Codegröße zu reduzieren.

Der Compiler gibt eine Warnung aus, wenn eine mit @abstract gekennzeichnete Methode eine nicht leere Implementierung aufweist.

Beispiel:
/** @abstract */
foo.MyClass.prototype.abstractMethod = function() {};
@const

Kennzeichnet eine Variable als schreibgeschützt. Der Compiler kann @const-Variablen inline einbinden, wodurch der JavaScript-Code optimiert wird.

Die Typdeklaration ist optional.

Der Compiler gibt eine Warnung aus, wenn einer mit @const markierten Variable mehr als einmal ein Wert zugewiesen wird. Wenn die Variable ein Objekt ist, sind Änderungen an den Eigenschaften des Objekts nicht zulässig.

Beispiel:
/** @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 @constructor-Annotation für jede Funktion, die mit dem Schlüsselwort new verwendet wird.

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 @dict werden Objekte mit unterschiedlichen Attributen erstellt. Wenn ein Konstruktor (im Beispiel Foo) mit @dict annotiert ist, können Sie nur die eckige Klammer verwenden, um auf die Attribute von Foo-Objekten zuzugreifen. Die Annotation kann auch direkt für Objektliterale verwendet werden.

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 @enum-Tag muss ein Typausdruck folgen.

Das Typlabel einer Aufzählung gilt für jedes Attribut der Aufzählung. Wenn eine Aufzählung beispielsweise den Typ number hat, muss jede ihrer Enum-Attribute eine Zahl sein. Wird der Typ einer Aufzählung weggelassen, wird number verwendet.

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 --generate_exports ausgeführt wird, generiert er den Code:

goog.exportProperty(foo.MyPublicClass.prototype, 'myPublicMethod',
  foo.MyPublicClass.prototype.myPublicMethod);

Dadurch werden die Symbole in unkompilierten Code exportiert. Sie können /** @export {SomeType} */ als Kurzschreibweise für

/**
 * @export
 * @type {SomeType}
 */
schreiben

Code, der die Annotation @export verwendet, muss entweder

  1. closure/base.js einschließen oder
  2. sowohl goog.exportSymbol als auch goog.exportProperty mit derselben Methodensignatur in ihrer eigenen Codebasis definieren.
@extends

Kennzeichnet eine Klasse oder Schnittstelle als von einer anderen Klasse übernommen. Eine mit @extends gekennzeichnete Klasse muss auch mit @constructor oder @interface gekennzeichnet sein.

Hinweis: @extends bewirkt nicht, dass eine Klasse von einer anderen Klasse übernimmt. Die Annotation teilt dem Compiler einfach mit, dass er eine Klasse während der Typprüfung als abgeleitete Klasse einer anderen behandeln kann.

Ein Beispiel für die Implementierung der Übernahme finden Sie unter Funktion „Closure Library“ goog.inherits().

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 @constructor verwendet, um anzugeben, dass eine Klasse eine Schnittstelle implementiert.

Der Compiler gibt eine Warnung aus, wenn Sie einen Konstruktor mit @implements taggen und dann nicht alle von der Schnittstelle definierten Methoden und Attribute implementieren.

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. element.innerHTML kann beispielsweise ein beliebiger Typ zugewiesen werden, es wird jedoch immer ein String 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 @inheritDoc impliziert das Tag @override.

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 @implements.

Der Compiler überprüft, ob Schnittstellen nicht instanziiert sind. Wenn das Schlüsselwort new mit einer Schnittstellenfunktion verwendet wird, gibt der Compiler eine Warnung aus.

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. @type {Foo} bedeutet beispielsweise „eine Instanz von Foo“, aber @lends {Foo} bedeutet „der Konstruktor Foo“.

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 @nocollapse besteht darin, das Exportieren änderbarer Attribute zu ermöglichen. Beachten Sie, dass nicht minimierte Attribute vom Compiler weiterhin umbenannt werden können. Wenn Sie eine Property, die ein Objekt mit @nocollapse ist, mit einer Anmerkung versehen, bleiben alle ihre Attribute ebenfalls minimiert.

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 extern files zulässig.

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 @package gekennzeichnet sind. Insbesondere kann Code in übergeordneten und untergeordneten Verzeichnissen nicht auf Namen zugreifen, die mit @package gekennzeichnet sind.

Öffentliche Konstruktoren können Attribute vom Typ @package haben, um die Methoden einzuschränken, die Aufrufer außerhalb des Verzeichnisses verwenden können. @package-Konstruktoren können jedoch öffentliche Attribute haben, um zu verhindern, dass Aufrufer außerhalb des Verzeichnisses einen Typ direkt instanziieren.

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. @param-Tags müssen in derselben Reihenfolge wie die Parameter in der Funktionsdefinition angegeben werden.

Auf das Tag @param muss ein Typausdruck folgen.

Alternativ können Sie die Parametertypen inline annotieren (siehe Beispiel foo).

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 @private gekennzeichnet sind. Konstruktoren, die als @private gekennzeichnet sind, können nur durch Code in derselben Datei und durch ihre statischen und Instanzmitglieder instanziiert werden.

Auf die öffentlichen statischen Attribute von als @private gekennzeichneten Konstruktoren kann auch von überall aus zugegriffen werden. Der Operator instanceof kann immer auf @private-Mitglieder zugreifen.

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 @protected kann aufgerufen werden:

  • den gesamten Code in derselben Datei
  • Statische Methoden und Instanzmethoden einer abgeleiteten Klasse der Klasse, für die das Attribut definiert ist.

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 @interface, ermöglicht jedoch implizite Implementierungen. Dies bedeutet, dass die Klasse in allen Klassen mit den Methoden und Eigenschaften implementiert wird, die im Prototoype der Strukturschnittstelle definiert sind, unabhängig davon, ob sie das Tag @implements verwendet. Datensatztypen und Objektliterale implementieren implizit auch eine strukturelle Schnittstelle, wenn sie die erforderlichen Attribute enthalten.

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 @return muss ein Typausdruck folgen.

Alternativ können Sie den Rückgabetyp inline angeben (siehe Beispiel foo).

Wenn eine Funktion, die nicht in extern enthalten ist, keinen Rückgabewert hat, können Sie das Tag @return weglassen. Der Compiler geht dann davon aus, dass die Funktion undefined zurückgibt.

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 @struct werden Objekte mit einer festen Anzahl von Attributen erstellt. Wenn ein Konstruktor (im Beispiel Foo) mit @struct annotiert ist, können Sie nur die Punktnotation verwenden, um auf die Attribute von Foo-Objekten und nicht auf die eckige Klammer zuzugreifen. Außerdem können Sie einer Foo-Instanz nach ihrer Konstruktion kein Attribut hinzufügen. Die Annotation kann auch direkt für Objektliterale verwendet werden.

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 this innerhalb einer Funktion verweist. Auf das Tag @this muss ein Typausdruck folgen.

Um Compiler-Warnungen zu vermeiden, müssen Sie die Annotation @this immer verwenden, wenn this in einer Funktion erscheint, die weder ein Prototyp noch eine als @constructor gekennzeichnete Funktion ist.

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 @type muss ein Typausdruck folgen.

Wenn Sie eine Variable oder einen Funktionsparameter deklarieren, können Sie die Typannotation wie im zweiten Beispiel inline weglassen und dabei {} und @type weglassen. Diese Tastenkombination kann nur verwendet werden, wenn eine Variable oder ein Funktionsparameter deklariert ist. Wenn Sie den Typ später anpassen möchten, benötigen Sie eine Umwandlung von Typ.

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 @struct noch vom Typ @dict ist. Dies ist die Standardeinstellung. Sie muss normalerweise nicht explizit geschrieben werden, es sei denn, Sie verwenden goog.defineClass oder das Schlüsselwort class, mit denen beide Klassen standardmäßig @structs sind.

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.

{Object<string, number>}
Ein Objekt, bei dem die Schlüssel Strings und die Werte Zahlen sind.

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 Array mit dem Attribut length angeben:
Array<{length}>. Im Beispiel links geben die äußeren geschweiften Klammern an, dass dies ein Typausdruck ist, und die inneren geschweiften Klammern geben an, dass dies ein Datensatztyp ist.

Typ „Nullwerte zulässig“ {?number}
Eine Zahl oder null.

Gibt an, dass ein Wert vom Typ A oder null ist.

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 @param-Annotation beschriebene Argument optional ist. Ein Funktionsaufruf kann ein optionales Argument weglassen. Ein optionaler Parameter kann einem nicht optionalen Parameter in der Parameterliste nicht vorangestellt werden.

Wenn ein Methodenaufruf einen optionalen Parameter auslässt, hat dieses Argument den Wert undefined. Wenn die Methode den Wert des Parameters in einem Klassenattribut speichert, muss die Typdeklaration dieses Attributs daher den Wert undefined enthalten. Beispiel:

/**
 * 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