Closure Compiler için JavaScript'e açıklama ekleme

Not: Bu sayfa güncel değil. Tam liste şu adreste tutulur: https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler

Genel Bakış

Closure Compiler, JavaScript değişkenleriyle ilgili veri türü bilgilerini kullanarak gelişmiş optimizasyon ve uyarılar sağlayabilir. Ancak JavaScript'te türleri bildirme yolu yoktur.

JavaScript'te değişken türünü bildirmek için söz dizimi olmadığından veri türünü belirtmek üzere kodda yorum kullanmanız gerekir.

Closure Compiler'ın tür dili, JSDoc belge oluşturma aracı tarafından kullanılan ek açıklamalardan türetilmiştir ancak o zamandan beri farklılaşmıştır. Artık JSDoc'un desteklemediği çeşitli ek açıklamalar içeriyor ve bunun tersi de geçerli. Bu belgede, Closure Compiler'ın anladığı ek açıklamalar ve tür ifadeleri açıklanmaktadır.

  1. JSDoc Etiketleri
  2. Tür İfadeleri
  3. Genel Türler

JSDoc Etiketleri

Closure Compiler, tür bilgilerini JSDoc etiketlerinde arar. Derleyicinin kodunuzu optimize etmesine ve olası tür hataları ile diğer hataları kontrol etmesine yardımcı olmak için aşağıdaki referans tablosunda açıklanan JSDoc etiketlerini kullanın.

Bu tablo yalnızca Closure Compiler'ın davranışını etkileyen etiketleri içerir. Diğer JSDoc etiketleri hakkında bilgi edinmek için JSDoc Toolkit dokümanlarına bakın.

Etiket Açıklama
@abstract

Bir yöntemi soyut olarak işaretler. goog.abstractMethod yöntemini ayarlamaya benzer şekilde, derleyici, kod boyutunu küçültmek için @abstract ile açıklama eklenmiş yöntemleri budayabilir.

Derleyici, @abstract ile işaretlenmiş bir yöntemin boş olmayan bir uygulaması varsa uyarı verir.

Örneğin:
/** @abstract */
foo.MyClass.prototype.abstractMethod = function() {};
@const

Bir değişkeni salt okunur olarak işaretler. Derleyici, JavaScript kodunu optimize eden @const değişkenlerini satır içi yapabilir.

Tür bildirimi isteğe bağlıdır.

Derleyici, @const ile işaretlenmiş bir değişkene birden fazla kez değer atanırsa uyarı verir. Değişken bir nesneyse derleyicinin nesnenin özelliklerinde değişiklik yapılmasını yasaklamadığını unutmayın.

Örneğin:
/** @const */ var MY_BEER = 'stout';

/**
 * My namespace's favorite kind of beer.
 * @const {string}
 */
mynamespace.MY_BEER = 'stout';

/** @const */ MyClass.MY_BEER = 'stout';
@constructor

Bir işlevi oluşturucu olarak işaretler. Derleyici, new anahtar kelimesiyle kullanılan tüm işlevler için @constructor ek açıklaması gerektirir.

Örneğin:

/**
 * A rectangle.
 * @constructor
 */
function GM_Rect() {
  ...
}
@define Derleyici tarafından derleme zamanında geçersiz kılınabilecek bir sabiti gösterir. Soldaki örnekte, ENABLE_DEBUG değerini false olarak değiştirmek için derleyiciye --define='ENABLE_DEBUG=false' işaretini iletebilirsiniz. Tanımlanmış bir sabitin türü sayı, dize veya boole olabilir. Tanımlara yalnızca genel kapsamda izin verilir.

Örneğin:

/** @define {boolean} */
var ENABLE_DEBUG = true;

/** @define {boolean} */
goog.userAgent.ASSUME_IE = false;
@deprecated

Bir işlevi, yöntemi veya özelliği işaretleyerek kullanılmasının artık kullanılmaması gerektiğini belirten bir derleyici uyarısı oluşturmasını sağlar.

Örneğin:

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

@dict, değişken sayıda özelliğe sahip nesneler oluşturmak için kullanılır. Bir oluşturucu (örnekteki Foo) @dict ile açıklama eklenmişse Foo nesnelerinin özelliklerine erişmek için yalnızca köşeli parantez gösterimini kullanabilirsiniz. Açıklama, doğrudan nesne değişmezleri üzerinde de kullanılabilir.

Örneğin:

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

Bir enum'un türünü belirtir. Enum, özellikleri bir dizi ilgili sabitten oluşan bir nesnedir. @enum etiketinin ardından bir tür ifadesi gelmelidir.

Bir enum'ın tür etiketi, enum'ın her özelliği için geçerlidir. Örneğin, bir enum'ın türü number ise numaralandırılmış özelliklerinin her biri sayı olmalıdır. Bir enum'ın türü belirtilmezse number olduğu varsayılır.

Örneğin:

/**
 * Enum for tri-state values.
 * @enum {number}
 */
project.TriState = {
  TRUE: 1,
  FALSE: -1,
  MAYBE: 0
};
@export

Bu kodu göz önünde bulundurarak

/** @export */
foo.MyPublicClass.prototype.myPublicMethod = function() {
  // ...
};

Derleyici --generate_exports işaretiyle çalıştırıldığında kodu oluşturur:

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

Bu işlem, sembolleri derlenmemiş koda aktarır. /** @export {SomeType} */ kısaltmasıyla

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

@export ek açıklamasını kullanan kod,

  1. closure/base.js veya
  2. goog.exportSymbol ve goog.exportProperty özelliklerini kendi kod tabanlarında aynı yöntem imzasıyla tanımlayın.
@extends

Bir sınıfı veya arayüzü başka bir sınıftan devralınmış olarak işaretler. @extends ile işaretlenmiş bir sınıf, @constructor veya @interface ile de işaretlenmelidir.

Not: @extends, bir sınıfın başka bir sınıftan devralmasına neden olmaz. Ek açıklama, derleyiciye tür kontrolü sırasında bir sınıfı başka bir sınıfın alt sınıfı olarak değerlendirebileceğini bildirir.

Devralma ile ilgili örnek uygulama için Closure Library işlevine goog.inherits() bakın.

Örneğin:

/**
 * Immutable empty node list.
 * @constructor
 * @extends {goog.ds.BasicNodeList}
 */
goog.ds.EmptyNodeList = function() {
  ...
};
@final

Bu sınıfın genişletilmesine izin verilmediğini gösterir. Yöntemler için, hiçbir alt sınıfın bu yöntemi geçersiz kılmaya izin verilmediğini gösterir.

Örneğin:

/**
 * A class that cannot be extended.
 * @final
 * @constructor
 */
sloth.MyFinalClass = function() { ... }

/**
 * A method that cannot be overridden.
 * @final
 */
sloth.MyFinalClass.prototype.method = function() { ... };
@implements

Bir sınıfın arayüz uyguladığını belirtmek için @constructor ile birlikte kullanılır.

Bir oluşturucuyu @implements ile etiketleyip arayüz tarafından tanımlanan tüm yöntemleri ve özellikleri uygulamadığınızda derleyici uyarı verir.

Örneğin:

/**
 * A shape.
 * @interface
 */
function Shape() {};
Shape.prototype.draw = function() {};

/**
 * @constructor
 * @implements {Shape}
 */
function Square() {};
Square.prototype.draw = function() {
  ...
};
@implicitCast

Bu ek açıklama yalnızca externs özellik bildirimlerinde görünebilir. Mülkün türü belirtilmiş ancak uyarı almadan istediğiniz türü atayabilirsiniz. Özelliğe erişirken, bildirilen türün değerini geri alırsınız. Örneğin, element.innerHTML değişkenine herhangi bir tür atanabilir ancak bu değişken her zaman bir dize döndürür.

/**
 * @type {string}
 * @implicitCast
 */
Element.prototype.innerHTML;
@inheritDoc

Bir alt sınıfın yönteminin veya özelliğinin, üst sınıfın yöntemini veya özelliğini kasıtlı olarak gizlediğini ve tam olarak aynı belgelere sahip olduğunu gösterir. @inheritDoc etiketinin @override etiketini içerdiğini unutmayın.

Örneğin:

/** @inheritDoc */
project.SubClass.prototype.toString = function() {
  ...
};
@interface

Bir işlevi arayüz olarak işaretler. Arayüz, bir türün gerekli üyelerini belirtir. Bir arayüzü uygulayan herhangi bir sınıf, arayüzün prototipinde tanımlanan tüm yöntemleri ve özellikleri uygulamalıdır. @implements sayfasına göz atın.

Derleyici, arayüzlerin örneklenmediğini doğrular. new anahtar kelimesi bir arayüz işleviyle kullanılıyorsa derleyici uyarı verir.

Örneğin:

/**
 * A shape.
 * @interface
 */
function Shape() {};
Shape.prototype.draw = function() {};

/**
 * A polygon.
 * @interface
 * @extends {Shape}
 */
function Polygon() {};
Polygon.prototype.getSides = function() {};
@lends

Bir nesne değişmezinin anahtarlarının başka bir nesnenin özellikleri olarak ele alınması gerektiğini belirtir. Bu ek açıklama yalnızca nesne değişmezlerinde görünmelidir.

Küme parantezleri içindeki adın, diğer açıklamalardaki gibi bir tür adı olmadığını unutmayın. Bu bir nesne adıdır. Özelliklerin verildiği nesneyi adlandırır. Örneğin, @type {Foo} "Foo örneği" anlamına gelirken @lends {Foo} "Foo oluşturucusu" anlamına gelir.

Bu ek açıklama hakkında daha fazla bilgiyi JSDoc Toolkit dokümanlarında bulabilirsiniz.

Örneğin:

goog.object.extend(
    Button.prototype,
    /** @lends {Button.prototype} */ ({
      isButton: function() { return true; }
    }));
@license veya @preserve

Derleyiciye, işaretli dosyanın derlenmiş kodundan önce ilişkili yorumu eklemesini söyler. Bu ek açıklama, önemli bildirimlerin (ör. yasal lisanslar veya telif hakkı metni) derleme sırasında değişmeden kalmasını sağlar. Satır sonları korunur.

Örneğin:

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

Derleyici tarafından bir değişkene daraltılmaması gereken bir özelliği belirtir. @nocollapse özelliğinin birincil kullanım amacı, değiştirilebilir özelliklerin dışa aktarılmasına izin vermektir. Daraltılmamış özelliklerin derleyici tarafından yeniden adlandırılabileceğini unutmayın. @nocollapse ile bir nesne olan bir özelliğe ek açıklama eklerseniz tüm özellikleri de daraltılmamış olarak kalır.

Örneğin:

/**
 * A namespace.
 * @const
 */
var foo = {};

/**
 * @nocollapse
 */
foo.bar = 42;

window['foobar'] = foo.bar;
@nosideeffects

Bildirilen harici işlevin çağrısının yan etkisi olmadığını gösterir. Bu ek açıklama, derleyicinin dönüş değeri kullanılmıyorsa işlev çağrılarını kaldırmasına olanak tanır. Ek açıklamaya yalnızca extern files içinde izin verilir.

Örneğin:

/** @nosideeffects */
function noSideEffectsFn1() {}

/** @nosideeffects */
var noSideEffectsFn2 = function() {};

/** @nosideeffects */
a.prototype.noSideEffectsFn3 = function() {};
@override

Bir alt sınıfın yönteminin veya özelliğinin, üst sınıfın yöntemini ya da özelliğini kasıtlı olarak gizlediğini gösterir. Başka ek açıklamalar yoksa yöntem veya özellik, ek açıklamaları üst sınıfından otomatik olarak devralır.

Örneğin:

/**
 * @return {string} Human-readable representation of
 *     project.SubClass.
 * @override
 */
project.SubClass.prototype.toString = function() {
  ...
};
@package

Bir üyeyi veya özelliği paket özel olarak işaretler. Yalnızca aynı dizindeki kod, @package ile işaretlenmiş adlara erişebilir. Özellikle, üst ve alt dizinlerdeki kodlar, @package ile işaretlenmiş adlara erişemez.

Herkese açık oluşturucular, dizinin dışındaki arayanların kullanabileceği yöntemleri kısıtlamak için @package özelliklerine sahip olabilir. Diğer yandan, @package oluşturucular, dizin dışındaki arayanların bir türü doğrudan örneklemesini önlemek için herkese açık özelliklere sahip olabilir.

Örneğin:

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

İşlev bağımsız değişkenlerinin türlerini belirtmek için yöntem, işlev ve oluşturucu tanımlarıyla birlikte kullanılır. @param etiketleri, işlev tanımındaki parametrelerle aynı sırada olmalıdır.

@param etiketinin ardından bir tür ifadesi gelmelidir.

Alternatif olarak, parametre türlerini satır içi olarak da açıklayabilirsiniz (örnekteki foo işlevine bakın).

Örneğin:

/**
 * 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;
}
Bir yapı bozma kalıbı olan parametreler için tür açıklamasından sonra geçerli bir JS tanımlayıcısı olan herhangi bir adı kullanabilirsiniz.
/**
 * @param {{name: string, age: number}} person
 */
function logPerson({name, age}) {
  console.log(`${name} is ${age} years old`);
}
@private

Bir üyeyi özel olarak işaretler. Yalnızca aynı dosyadaki kod, @private ile işaretlenmiş genel değişkenlere ve işlevlere erişebilir. @private ile işaretlenen oluşturucular yalnızca aynı dosyadaki kod ve statik ile örnek üyeleri tarafından örneklenebilir.

@private ile işaretlenmiş oluşturucuların herkese açık statik özelliklerine de her yerden erişilebilir ve instanceof operatörü her zaman @private üyelerine erişebilir.

Örneğin:

/**
 * Handlers that are listening to this logger.
 * @private {Array<Function>}
 */
this.handlers_ = [];
@protected

Bir üyenin veya mülkün korunduğunu gösterir.

@protected olarak işaretlenen bir mülke şu kullanıcılar erişebilir:

  • Tüm kodlar aynı dosyada
  • özelliğin tanımlandığı sınıfın herhangi bir alt sınıfının statik yöntemleri ve örnek yöntemleri.

Örneğin:

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

Bir işlevi yapısal arayüz olarak işaretler. Yapısal arayüz, nominal @interface'e benzer ancak örtülü uygulamalara izin verir. Bu, yapısal arayüzün prototipinde tanımlanan yöntemleri ve özellikleri içeren tüm sınıfların, @implements etiketini kullanıp kullanmadığına bakılmaksızın yapısal arayüzü uyguladığı anlamına gelir. Kayıt türleri ve nesne değişmezleri de gerekli özellikleri içeriyorsa yapısal bir arayüzü örtülü olarak uygular.

Örneğin:

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

Yöntem ve işlev tanımlarının dönüş türlerini belirtir. @return etiketinin ardından bir tür ifadesi gelmelidir.

Alternatif olarak, satır içi dönüş türüne açıklama ekleyebilirsiniz (örnekteki foo işlevine bakın).

Externs'te bulunmayan bir işlevin dönüş değeri yoksa @return etiketini atlayabilirsiniz. Bu durumda derleyici, işlevin undefined döndürdüğünü varsayar.

Örneğin:

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

@struct, sabit sayıda özellik içeren nesneler oluşturmak için kullanılır. Bir oluşturucu (örnekteki Foo) @struct ile açıklama eklenmişse Foo nesnelerinin özelliklerine erişmek için yalnızca nokta gösterimini kullanabilirsiniz, köşeli parantez gösterimini kullanamazsınız. Ayrıca, bir Foo örneği oluşturulduktan sonra bu örneğe mülk ekleyemezsiniz. Açıklama, doğrudan nesne değişmezleri üzerinde de kullanılabilir.

Örneğin:

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

Genel Türler başlıklı makaleyi inceleyin.

Örneğin:

/**
 * @param {T} t
 * @constructor
 * @template T
 */
Container = function(t) { ... };
@this

Bir işlevde anahtar kelimenin this atıfta bulunduğu nesnenin türünü belirtir. @this etiketinin ardından bir tür ifadesi gelmelidir.

Derleyici uyarılarını önlemek için, prototip yöntemi olmayan veya @constructor olarak işaretlenmiş bir işlevde this her göründüğünde @this ek açıklamasını kullanmanız gerekir.

Örneğin:

chat.RosterWidget.extern('getRosterElement',
    /**
     * Returns the roster widget element.
     * @this {Widget}
     * @return {Element}
     */
    function() {
      return this.getComponent().getElement();
    });
@throws

Bir işlev tarafından oluşturulan istisnaları belgelemek için kullanılır. Tür denetleyicisi şu anda bu bilgileri kullanmamaktadır. Yalnızca bir externs dosyasında tanımlanan bir işlevin yan etkileri olup olmadığını belirlemek için kullanılır.

Örneğin:

/**
 * @throws {DOMException}
 */
DOMApplicationCache.prototype.swapCache = function() { ... };
@type

Bir değişkenin, özelliğin veya ifadenin türünü tanımlar. @type etiketi, tür ifadesi ile devam etmelidir.

Bir değişken veya işlev parametresi bildirirken, ikinci örnekte olduğu gibi {} ve @type karakterlerini atlayarak tür açıklamasını satır içi yazabilirsiniz. Bu kısayol yalnızca bir değişken veya işlev parametresinin bildirildiği yerlerde kullanılabilir. Türünü daha sonra ayarlamak isterseniz tür dönüşümü yapmanız gerekir.

Örneğin:

/**
 * The message hex ID.
 * @type {string}
 */
var hexId = hexId;
var /** string */ name = 'Jamie';
function useSomething(/** (string|number|!Object) */ something) {
...
}
@typedef

Daha karmaşık bir tür için bir takma ad bildirir. Şu anda typedef'ler yalnızca üst düzeyde tanımlanabilir, işlevlerin içinde tanımlanamaz. Bu sınırlamayı yeni tür çıkarımında düzelttik.

Örneğin:

/** @typedef {(string|number)} */
goog.NumberLike;

/** @param {goog.NumberLike} x A number or a string. */
goog.readNumber = function(x) {
  ...
}
@unrestricted

Bir sınıfın @struct türü veya @dict türü olmadığını gösterir. Bu varsayılan değer olduğundan, genellikle açıkça yazılması gerekmez. Ancak hem varsayılan olarak @struct olan sınıflar üreten class anahtar kelimesini kullanmıyorsanız bu durum geçerlidir.

Örneğin:

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

Tür İfadeleri

Herhangi bir değişkenin, özelliğin, ifadenin veya işlev parametresinin veri türünü tür ifadesi ile belirtebilirsiniz. Tür ifadesi, aşağıda açıklanan tür operatörlerinin bir kombinasyonunu içeren küme parantezlerinden ("{ }") oluşur.

Bir işlev parametresinin türünü bildirmek için @param etiketiyle birlikte bir tür ifadesi kullanın. Bir değişkenin, özelliğin veya ifadenin türünü bildirmek için @type etiketiyle birlikte bir tür ifadesi kullanın.

Kodunuzda ne kadar çok tür belirtirseniz derleyici o kadar çok optimizasyon yapabilir ve o kadar çok hata yakalayabilir.

Derleyici, programınızda tür kontrolü yapmak için bu ek açıklamaları kullanır. Closure Compiler'ın, programınızdaki her ifadenin türünü belirleyebileceğine dair herhangi bir söz vermediğini unutmayın. Değişkenlerin nasıl kullanıldığına ve bildirimlerine eklenen tür ek açıklamalarına bakarak en iyi sonucu elde etmeye çalışır. Ardından, mümkün olduğunca çok sayıda ifadenin türünü belirlemek için bir dizi tür çıkarımı algoritması kullanır. Bu algoritmalardan bazıları basittir ("x bir sayıysa ve y = x; ifadesini görüyorsak y bir sayıdır"). Bazıları daha dolaylıdır ("f'nin ilk parametresi, sayı alması gereken bir geri çağırma olarak belgelenmişse ve f(function(x) { /** ... */ }); görülüyorsa x bir sayı olmalıdır").

Operatör Adı Söz Dizimi Örnekleri Açıklama
Tür Adı {boolean}
{Window}
{goog.ui.Menu}
Bir türün adını belirtir.
Uygulama Türü {Array<string>}
Dizeler dizisi.

{Object<string, number>}
Anahtarların dize, değerlerin ise sayı olduğu bir nesne.

Bir türü bir dizi tür bağımsız değişkeniyle parametrelendirir. Java'daki genel türlere benzer.
Type Union {(number|boolean)}
Sayı veya Boole değeri.

Parantezlerin zorunlu olduğunu unutmayın.
Bir değerin A TÜRÜ veya B TÜRÜ olabileceğini gösterir.
Kayıt Türü {{myNum: number, myObject}}
Hem myNum adlı bir özelliğe (number türünde bir değere sahip) hem de myObject adlı bir özelliğe (herhangi bir türde değere sahip) sahip anonim bir tür.

Değerin, belirtilen türlerdeki değerlere sahip belirtilen üyeleri içerdiğini gösterir.

Küme parantezleri, tür söz diziminin bir parçasıdır. Örneğin, length özelliği olan bir Array nesne grubunu belirtmek için
Array<{length}> yazabilirsiniz. Soldaki örnekte, dış ayraçlar bunun bir tür ifadesi olduğunu, iç ayraçlar ise bunun bir kayıt türü olduğunu gösterir.

Boş değer atanabilir tür {?number}
Bir sayı veya null.

Bir değerin A türünde veya null olduğunu gösterir.

Tüm nesne türleri, Nullable operatörüyle bildirilip bildirilmediklerine bakılmaksızın varsayılan olarak boş değer atanabilir. Nesne türü, işlev, dize, sayı veya boole dışında herhangi bir şey olarak tanımlanır. Bir nesne türünü boş değer atanamaz yapmak için Non-nullable (Boş değer atanamaz) operatörünü kullanın.

Null yapılamayan tür {!Object}
Bir nesne, ancak hiçbir zaman null değeri değil.

Bir değerin A türünde olduğunu ve boş olmadığını gösterir.

İşlevler ve tüm değer türleri (boole, sayı ve dize), Non-nullable operatörüyle bildirilip bildirilmediklerine bakılmaksızın varsayılan olarak boş değer atanabilir değildir. Bir değer veya işlev türünü boş değer atanabilir yapmak için Nullable operatörünü kullanın.

İşlev Türü {function(string, boolean)}
İki parametre (bir dize ve bir boole) alan ve bilinmeyen bir dönüş değerine sahip bir işlev.
Bir işlevi ve işlevin parametre türlerini belirtir.
İşlevin Dönüş Türü {function(): number}
Parametre almayan ve sayı döndüren bir işlev.
Bir işlevin dönüş değerinin türünü belirtir.
İşlev this Türü {function(this:goog.ui.Menu, string)}
Bir parametre (dize) alan ve goog.ui.Menu bağlamında yürütülen bir işlev.
İşlevdeki this değerinin türünü belirtir.
İşlev new Türü {function(new:goog.ui.Menu, string)}
Bir parametre (dize) alan ve "new" anahtar kelimesiyle çağrıldığında goog.ui.Menu'nün yeni bir örneğini oluşturan işlev.
Oluşturucunun oluşturulan türünü belirtir.
Değişken parametreler {function(string, ...number): number}
Bir parametre (dize) alan ve ardından sayı olması gereken değişken sayıda parametre alan bir işlev.
Bir işlev türünün değişken sayıda parametre aldığını belirtir ve değişken parametreler için bir tür tanımlar.
Değişken parametreler (@param ek açıklamalarında) @param {...number} var_args
Açıklama eklenmiş bir işlev için değişken sayıda parametre.
Açıklama eklenen işlevin değişken sayıda parametre kabul ettiğini belirtir ve değişken parametreler için bir tür tanımlar.
@param ek açıklamasındaki isteğe bağlı parametre @param {number=} opt_argument
number türünde isteğe bağlı bir parametre.

@param ek açıklamasıyla açıklanan bağımsız değişkenin isteğe bağlı olduğunu gösterir. İşlev çağrısında isteğe bağlı bir bağımsız değişken atlanabilir. İsteğe bağlı bir parametre, parametre listesinde zorunlu olmayan bir parametreden önce gelemez.

Bir yöntem çağrısında isteğe bağlı bir parametre atlanırsa bu bağımsız değişkenin değeri undefined olur. Bu nedenle, yöntem parametrenin değerini bir sınıf özelliğinde saklıyorsa bu özelliğin tür bildirimi, aşağıdaki örnekte olduğu gibi olası bir undefined değeri içermelidir:

/**
 * 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;
}
İşlev türünde isteğe bağlı bağımsız değişken {function(?string=, number=)}
Bir isteğe bağlı, boş değer atanabilir dize ve bir isteğe bağlı sayıyı bağımsız değişken olarak alan bir işlev.
Bir işlev türündeki bağımsız değişkenin isteğe bağlı olduğunu gösterir. İsteğe bağlı bir bağımsız değişken, işlev çağrısından çıkarılabilir. Bağımsız değişken listesinde isteğe bağlı bir bağımsız değişken, isteğe bağlı olmayan bir bağımsız değişkenden önce gelemez.
ALL türü {*} Değişkenin herhangi bir türü alabileceğini gösterir.
UNKNOWN türü {?} Değişkenin herhangi bir türü alabileceğini ve derleyicinin, değişkenin kullanımlarını tür denetimine tabi tutmaması gerektiğini belirtir.

Tür Dönüşümü (Type Casting)

Bir değeri belirli bir türe yayınlamak için şu söz dizimini kullanın:

/** @type {!MyType} */ (valueExpression)
İfadenin etrafındaki parantezler her zaman gereklidir.

Genel Türler

Java'ya benzer şekilde Closure Compiler, genel türleri, işlevleri ve yöntemleri destekler. Jenerikler, derleme zamanı tür güvenliğini korurken çeşitli türlerdeki nesneler üzerinde çalışır.

Belirli bir türdeki nesnelere referans içeren genelleştirilmiş koleksiyonları ve belirli bir türdeki nesneler üzerinde çalışan genelleştirilmiş algoritmaları uygulamak için genel türleri kullanabilirsiniz.

Genel Tür Bildirme

Bir tür, türün oluşturucusuna (sınıflar için) veya arayüz bildirimine (arayüzler için) @template eklenerek genel hale getirilebilir. Örneğin:

/**
 * @constructor
 * @template T
 */
Foo = function() { ... };

@template T açıklaması, Foo öğesinin bir şablon türü olan T ile genel bir tür olduğunu gösterir. T şablon türü, Foo tanımının kapsamı içinde tür olarak kullanılabilir. Örneğin:

/** @return {T} */
Foo.prototype.get = function() { ... };

/** @param {T} t */
Foo.prototype.set = function(t) { ... };

get yöntemi T türünde bir nesne döndürür ve set yöntemi yalnızca T türündeki nesneleri kabul eder.

Genel Türü Oluşturma

Yukarıdaki örneği tekrar kullanarak Foo öğesinin şablonlu bir örneği çeşitli şekillerde oluşturulabilir:

/** @type {!Foo<string>} */ var foo = new Foo();
var foo = /** @type {!Foo<string>} */ (new Foo());

Yukarıdaki her iki oluşturucu ifadesi de şablon türü T olan bir Foo örneği oluşturur.string Derleyici, foo yöntemlerine yapılan çağrıların ve foo özelliklerine yapılan erişimlerin, şablonlu türe uygun olmasını zorunlu kılar. Örneğin:

foo.set("hello");  // OK.
foo.set(3);        // Error - expected a string, found a number.
var x = foo.get(); // x is a string.

Örnekler, oluşturucu bağımsız değişkenleriyle de örtülü olarak türlendirilebilir. Farklı bir genel tür kullanmayı deneyin, Bar:

/**
 * @param {T} t
 * @constructor
 * @template T
 */
Bar = function(t) { ... };
var bar = new Bar("hello"); // bar is a Bar<string>

Bar oluşturucusunun bağımsız değişkeninin türü string olarak çıkarılır ve sonuç olarak oluşturulan örnek bar, Bar<string> olarak çıkarılır.

Birden Fazla Şablon Türü

Bir genel öğede herhangi bir sayıda şablon türü olabilir. Aşağıdaki harita sınıfında iki şablon türü vardır:

/**
 * @constructor
 * @template Key, Val
 */
MyMap = function() { ... };

Genel bir türün tüm şablon türleri, virgülle ayrılmış bir liste olarak aynı @template ek açıklamasında belirtilmelidir. Şablonlu tür ek açıklamaları, şablon türlerini değerlerle eşleştirmek için sıralamayı kullanacağından şablon türü adlarının sırası önemlidir. Örneğin:

/** @type {MyMap<string, number>} */ var map; // Key = string, Val = number.

Genel Türlerin Değişmezliği

Closure Compiler, değişmez genel türleri zorunlu kılar. Bu nedenle, bir bağlam Foo<X> türü bekliyorsa X ve Y farklı türler olduğunda, biri diğerinin alt türü olsa bile Foo<Y> türünü iletemezsiniz. Örneğin:

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

Genel Türlerin Devralınması

Genel türler devralınabilir ve şablon türleri sabit olabilir veya devralan türe yayılabilir. Aşağıda, üst türünün şablon türünü düzelten bir devralma türü örneği verilmiştir:

/**
 * @constructor
 * @template T
 */
A = function() { ... };

/** @param {T} t */
A.prototype.method = function(t) { ... };

/**
 * @constructor
 * @extends {A<string>}
 */
B = function() { ... };

A<string> genişletildiğinde B, string türünde bir parametre alan method yöntemine sahip olur.

Aşağıda, üst türünün şablon türünü yayan bir devralma türü örneği verilmiştir:

/**
 * @constructor
 * @template U
 * @extends {A<U>}
 */
C = function() { ... };

A<U> genişletilerek C öğesinin şablonlu örnekleri, şablon türü U parametresini alan bir method yöntemine sahip olur.

Arayüzler benzer şekilde uygulanabilir ve genişletilebilir ancak tek bir tür, aynı arayüzü farklı şablon türleriyle birden çok kez uygulayamaz. Örneğin:

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

Genel İşlevler ve Yöntemler

Genel türlere benzer şekilde, tanımlarına @template eklenerek işlevler ve yöntemler genel hale getirilebilir. Örneğin:

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