Catatan: Halaman ini sudah tidak berlaku. Daftar lengkap dikelola di https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler
Ringkasan
Compiler Closure dapat menggunakan informasi jenis data tentang variabel JavaScript untuk memberikan pengoptimalan dan peringatan yang lebih baik. JavaScript, namun, tidak memiliki cara untuk mendeklarasikan jenis.
Karena JavaScript tidak memiliki sintaksis untuk mendeklarasikan jenis variabel, Anda harus menggunakan komentar dalam kode untuk menentukan jenis data.
Bahasa jenis Closure Compiler berasal dari anotasi yang digunakan oleh alat pembuatan dokumen JSDoc, meskipun sejak itu telah berbeda. Sekarang, file ini menyertakan beberapa anotasi yang tidak didukung JSDoc, dan sebaliknya. Dokumen ini menjelaskan kumpulan anotasi dan ekspresi jenis yang dipahami oleh Closure Compiler.
Tag JSDoc
Compiler Closure mencari informasi jenis dalam tag JSDoc. Gunakan tag JSDoc yang dijelaskan dalam tabel referensi di bawah untuk membantu compiler mengoptimalkan kode Anda dan memeriksa kemungkinan error jenis dan kesalahan lainnya.
Tabel ini hanya menyertakan tag yang memengaruhi perilaku Closure Compiler. Untuk mengetahui informasi tentang tag JSDoc lainnya, lihat dokumentasi JSDoc Toolkit.
Tag | Deskripsi |
---|---|
@abstract
|
Menandai metode sebagai abstrak. Mirip dengan menyetel metode ke
Compiler akan menghasilkan peringatan jika metode yang ditandai dengan /** @abstract */ foo.MyClass.prototype.abstractMethod = function() {}; |
@const
|
Menandai variabel sebagai hanya baca. Compiler dapat
menggabungkan variabel Deklarasi jenis bersifat opsional.
Compiler akan menghasilkan peringatan jika variabel yang ditandai
dengan /** @const */ var MY_BEER = 'stout'; /** * My namespace's favorite kind of beer. * @const {string} */ mynamespace.MY_BEER = 'stout'; /** @const */ MyClass.MY_BEER = 'stout'; |
@constructor
|
Menandai fungsi sebagai konstruktor.
Compiler memerlukan anotasi Contoh: /** * A rectangle. * @constructor */ function GM_Rect() { ... } |
@define
|
Menunjukkan konstanta yang dapat diganti oleh compiler pada waktu kompilasi.
Dengan contoh di sebelah kiri, Anda dapat meneruskan tanda
--define='ENABLE_DEBUG=false'
ke compiler untuk mengubah nilai
ENABLE_DEBUG menjadi false.
Jenis konstanta yang ditentukan dapat berupa angka, string, atau boolean.
Definisi hanya diizinkan dalam cakupan global.
Contoh: /** @define {boolean} */ var ENABLE_DEBUG = true; /** @define {boolean} */ goog.userAgent.ASSUME_IE = false; |
@deprecated
|
Menandai fungsi, metode, atau properti sehingga penggunaannya akan menghasilkan peringatan compiler yang menunjukkan bahwa fungsi, metode, atau properti tersebut tidak boleh digunakan lagi. Contoh: /** * 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
|
Contoh: /** * @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
|
Menentukan jenis enum. Enum adalah objek yang propertinya
membentuk serangkaian konstanta terkait. Tag Label jenis enum berlaku untuk setiap properti
enum. Misalnya, jika enum memiliki jenis Contoh: /** * Enum for tri-state values. * @enum {number} */ project.TriState = { TRUE: 1, FALSE: -1, MAYBE: 0 }; |
@export
|
Mengingat kode ini /** @export */ foo.MyPublicClass.prototype.myPublicMethod = function() { // ... };
saat compiler dijalankan dengan tanda goog.exportProperty(foo.MyPublicClass.prototype, 'myPublicMethod', foo.MyPublicClass.prototype.myPublicMethod); yang akan mengekspor simbol ke kode yang tidak dikompilasi. Anda dapat menulis
/** * @export * @type {SomeType} */ Kode yang menggunakan anotasi
|
@extends
|
Menandai class atau antarmuka sebagai mewarisi dari class lain. Class yang ditandai dengan
Catatan:
Untuk contoh implementasi pewarisan, lihat
fungsi Closure
Library Contoh: /** * Immutable empty node list. * @constructor * @extends {goog.ds.BasicNodeList} */ goog.ds.EmptyNodeList = function() { ... }; |
@final
|
Menunjukkan bahwa class ini tidak boleh diperluas. Untuk metode, menunjukkan bahwa tidak ada subclass yang diizinkan untuk mengganti metode tersebut. Contoh: /** * A class that cannot be extended. * @final * @constructor */ sloth.MyFinalClass = function() { ... } /** * A method that cannot be overridden. * @final */ sloth.MyFinalClass.prototype.method = function() { ... }; |
@implements
|
Digunakan dengan
Compiler akan menampilkan peringatan jika Anda memberi tag pada konstruktor
dengan Contoh: /** * A shape. * @interface */ function Shape() {}; Shape.prototype.draw = function() {}; /** * @constructor * @implements {Shape} */ function Square() {}; Square.prototype.draw = function() { ... }; |
@implicitCast
|
Anotasi ini hanya dapat muncul dalam deklarasi properti externs.
Properti memiliki jenis yang dideklarasikan, tetapi Anda dapat menetapkan jenis apa pun ke
properti tersebut tanpa peringatan. Saat mengakses properti, Anda akan mendapatkan kembali
nilai jenis yang dideklarasikan. Misalnya, /** * @type {string} * @implicitCast */ Element.prototype.innerHTML; |
@inheritDoc
|
Menunjukkan bahwa metode atau properti subclass
dengan sengaja menyembunyikan metode atau properti superclass, dan memiliki
dokumentasi yang sama persis. Perhatikan bahwa
tag Contoh: /** @inheritDoc */ project.SubClass.prototype.toString = function() { ... }; |
@interface
|
Menandai fungsi sebagai antarmuka. Antarmuka menentukan
anggota yang diperlukan dari suatu jenis. Setiap class yang mengimplementasikan antarmuka
harus mengimplementasikan semua metode dan properti yang ditentukan pada
prototipe
antarmuka. Lihat
Compiler memverifikasi bahwa antarmuka tidak di-instansiasi. Jika
kata kunci Contoh: /** * A shape. * @interface */ function Shape() {}; Shape.prototype.draw = function() {}; /** * A polygon. * @interface * @extends {Shape} */ function Polygon() {}; Polygon.prototype.getSides = function() {}; |
@lends
|
Menunjukkan bahwa kunci literal objek harus diperlakukan sebagai properti objek lain. Anotasi ini hanya boleh muncul pada literal objek.
Perhatikan bahwa nama dalam tanda kurung bukan nama jenis seperti
dalam anotasi lainnya. Ini adalah nama objek. Objek yang dipinjamkan propertinya.
Misalnya, Dokumen JSDoc Toolkit memiliki informasi selengkapnya tentang anotasi ini. Contoh: goog.object.extend( Button.prototype, /** @lends {Button.prototype} */ ({ isButton: function() { return true; } })); |
@license atau @preserve
|
Memberi tahu compiler untuk menyisipkan komentar terkait sebelum kode yang dikompilasi untuk file yang ditandai. Anotasi ini memungkinkan pemberitahuan penting (seperti lisensi hukum atau teks hak cipta) untuk tetap tidak berubah setelah kompilasi. Pemisah baris akan dipertahankan. Contoh: /** * @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
|
Menunjukkan properti yang tidak boleh diciutkan oleh compiler menjadi variabel. Penggunaan utama Contoh: /** * A namespace. * @const */ var foo = {}; /** * @nocollapse */ foo.bar = 42; window['foobar'] = foo.bar; |
@nosideeffects
|
Menunjukkan bahwa panggilan ke fungsi eksternal yang dideklarasikan tidak memiliki efek samping.
Anotasi ini memungkinkan compiler menghapus panggilan ke fungsi
jika nilai yang ditampilkan tidak digunakan. Anotasi hanya diizinkan di
Contoh: /** @nosideeffects */ function noSideEffectsFn1() {} /** @nosideeffects */ var noSideEffectsFn2 = function() {}; /** @nosideeffects */ a.prototype.noSideEffectsFn3 = function() {}; |
@override
|
Menunjukkan bahwa metode atau properti subclass sengaja menyembunyikan metode atau properti superclass. Jika tidak ada anotasi lain yang disertakan, metode atau properti akan otomatis mewarisi anotasi dari superclass-nya. Contoh: /** * @return {string} Human-readable representation of * project.SubClass. * @override */ project.SubClass.prototype.toString = function() { ... }; |
@package
|
Menandai anggota atau properti sebagai pribadi paket. Hanya kode di direktori yang sama
yang dapat mengakses nama yang ditandai
Konstruktor publik dapat memiliki properti Contoh: /** * 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
|
Digunakan dengan definisi metode, fungsi, dan konstruktor untuk menentukan
jenis argumen fungsi. Tag
Tag
Atau, Anda dapat menganotasi jenis parameter secara inline
(lihat fungsi Contoh: /** * 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
|
Menandai anggota sebagai pribadi. Hanya kode dalam file yang sama yang dapat mengakses
variabel dan fungsi global
yang ditandai
Properti statis publik konstruktor yang ditandai Contoh: /** * Handlers that are listening to this logger. * @private {Array<Function>} */ this.handlers_ = []; |
@protected
|
Menunjukkan bahwa anggota atau properti dilindungi.
Properti yang ditandai
Contoh: /** * 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
|
Menandai fungsi sebagai antarmuka struktural. Antarmuka struktural
mirip dengan Contoh: /** * 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
|
Menentukan jenis nilai yang ditampilkan dari definisi metode dan fungsi.
Tag
Atau, Anda dapat menganotasi jenis nilai yang ditampilkan secara inline
(lihat fungsi
Jika fungsi yang tidak ada di externs tidak memiliki nilai yang ditampilkan, Anda dapat menghilangkan tag Contoh: /** * 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
|
Contoh: /** * @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
|
Lihat Jenis Generik. Contoh: /** * @param {T} t * @constructor * @template T */ Container = function(t) { ... }; |
@this
|
Menentukan jenis objek yang dirujuk oleh kata kunci
Untuk mencegah peringatan compiler, Anda harus menggunakan
anotasi Contoh: chat.RosterWidget.extern('getRosterElement', /** * Returns the roster widget element. * @this {Widget} * @return {Element} */ function() { return this.getComponent().getElement(); }); |
@throws
|
Digunakan untuk mendokumentasikan pengecualian yang dimunculkan oleh fungsi. Pemeriksa jenis saat ini tidak menggunakan informasi ini. Fungsi ini hanya digunakan untuk mengetahui apakah fungsi yang dideklarasikan dalam file externs memiliki efek samping. Contoh: /** * @throws {DOMException} */ DOMApplicationCache.prototype.swapCache = function() { ... }; |
@type
|
Mengidentifikasi jenis variabel, properti, atau
ekspresi. Tag Saat mendeklarasikan parameter variabel atau fungsi,
Anda dapat menulis anotasi jenis inline dengan menghilangkan
Contoh: /** * The message hex ID. * @type {string} */ var hexId = hexId; var /** string */ name = 'Jamie'; function useSomething(/** (string|number|!Object) */ something) { ... } |
@typedef
|
Mendeklarasikan alias untuk jenis yang lebih kompleks. Saat ini, typedef hanya dapat ditentukan di tingkat teratas, bukan di dalam fungsi. Kami telah memperbaiki batasan ini di inferensi jenis baru. Contoh: /** @typedef {(string|number)} */ goog.NumberLike; /** @param {goog.NumberLike} x A number or a string. */ goog.readNumber = function(x) { ... } |
@unrestricted
|
Menunjukkan bahwa class bukan jenis Contoh: /** * @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 |
Ekspresi Jenis
Anda dapat menentukan jenis data variabel, properti, ekspresi atau parameter fungsi dengan ekspresi jenis. Ekspresi jenis terdiri dari tanda kurung kurawal ("{ }") yang berisi beberapa kombinasi operator jenis yang dijelaskan di bawah.
Gunakan ekspresi jenis dengan
tag @param
untuk mendeklarasikan
jenis parameter fungsi. Gunakan ekspresi jenis dengan
tag @type
untuk mendeklarasikan
jenis variabel, properti, atau ekspresi.
Makin banyak jenis yang Anda tentukan dalam kode, makin banyak pengoptimalan yang dapat dilakukan compiler dan makin banyak kesalahan yang dapat ditangkapnya.
Compiler menggunakan anotasi ini untuk memeriksa jenis program Anda.
Perhatikan bahwa Closure Compiler tidak menjamin bahwa compiler tersebut akan dapat mengetahui jenis setiap ekspresi dalam program Anda. Inferensi ini berupaya sebaik mungkin dengan melihat cara variabel digunakan, dan anotasi jenis yang dilampirkan pada deklarasinya. Kemudian, compiler menggunakan sejumlah algoritma inferensi jenis untuk
mengetahui jenis sebanyak mungkin ekspresi. Beberapa algoritma ini sederhana ("jika x adalah angka, dan kita melihat y = x;
, maka y adalah angka"). Beberapa di antaranya lebih tidak langsung ("jika parameter pertama f's didokumentasikan sebagai callback yang harus mengambil angka, dan kita melihat f(function(x) { /** ... */ });
, maka x harus berupa angka").
Nama Operator | Contoh Sintaksis | Deskripsi |
---|---|---|
Ketik Nama |
{boolean} {Window} {goog.ui.Menu}
|
Menentukan nama jenis. |
Jenis Aplikasi |
{Array<string>} Array string.
|
Memarameterkan jenis dengan sekumpulan argumen jenis. Mirip dengan generik Java. |
Gabungan Jenis |
{(number|boolean)} Angka atau boolean. Perhatikan tanda kurung, yang diperlukan. |
Menunjukkan bahwa nilai mungkin memiliki jenis A ATAU jenis B. |
Jenis Data |
{{myNum: number, myObject}}
Jenis anonim dengan properti bernama myNum
yang memiliki nilai jenis number dan properti
bernama myObject yang memiliki nilai jenis apa pun.
|
Menunjukkan bahwa nilai memiliki anggota yang ditentukan dengan nilai jenis yang ditentukan. Kurung kurawal adalah bagian dari sintaksis jenis. Misalnya, untuk
menunjukkan |
Jenis nullable |
{?number} Angka atau null .
|
Menunjukkan bahwa nilai berjenis A atau Semua jenis objek dapat bernilai null secara default, baik dideklarasikan dengan operator Nullable maupun tidak. Jenis objek ditentukan sebagai apa pun kecuali fungsi, string, angka, atau boolean. Untuk membuat jenis objek tidak dapat bernilai null, gunakan operator Tidak dapat bernilai null. |
Jenis yang tidak dapat bernilai null |
{!Object} Objek, tetapi bukan nilai null .
|
Menunjukkan bahwa nilai adalah jenis A dan bukan null. Fungsi dan semua jenis nilai (boolean, angka, dan string) secara default tidak nullable, baik dideklarasikan dengan operator Non-nullable maupun tidak. Untuk membuat jenis nilai atau fungsi nullable, gunakan operator Nullable. |
Jenis Fungsi |
{function(string, boolean)} Fungsi yang menggunakan dua parameter (string dan boolean), dan memiliki nilai yang ditampilkan yang tidak diketahui. |
Menentukan fungsi dan jenis parameter fungsi. |
Jenis Nilai yang Ditampilkan Fungsi |
{function(): number} Fungsi yang tidak menggunakan parameter dan menampilkan angka. |
Menentukan jenis nilai yang ditampilkan fungsi. |
Jenis Fungsi this |
{function(this:goog.ui.Menu, string)} Fungsi yang mengambil satu parameter (string), dan dieksekusi dalam konteks goog.ui.Menu. |
Menentukan jenis nilai this dalam
fungsi. |
Jenis Fungsi new |
{function(new:goog.ui.Menu, string)} Fungsi yang menggunakan satu parameter (string), dan membuat instance goog.ui.Menu baru saat dipanggil dengan kata kunci 'new'. |
Menentukan jenis konstruksi konstruktor. |
Parameter variabel |
{function(string, ...number): number} Fungsi yang mengambil satu parameter (string), lalu sejumlah variabel parameter yang harus berupa angka. |
Menunjukkan bahwa jenis fungsi menggunakan sejumlah variabel parameter, dan menentukan jenis untuk parameter variabel. |
Parameter variabel (dalam anotasi @param )
|
@param {...number} var_args Jumlah parameter variabel ke fungsi yang dianotasi. |
Menunjukkan bahwa fungsi yang diberi anotasi menerima sejumlah variabel parameter, dan menentukan jenis untuk parameter variabel. |
Parameter opsional dalam anotasi @param
|
@param {number=} opt_argument Parameter opsional berjenis number .
|
Menunjukkan bahwa argumen yang dijelaskan oleh
anotasi
Jika panggilan metode menghilangkan parameter opsional, argumen tersebut akan memiliki
nilai /** * 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; } |
Argumen opsional dalam jenis fungsi |
{function(?string=, number=)} Fungsi yang menggunakan satu string opsional yang dapat bernilai null dan satu angka opsional sebagai argumen. |
Menunjukkan bahwa argumen dalam jenis fungsi bersifat opsional. Argumen opsional dapat dihilangkan dari panggilan fungsi. Argumen opsional tidak boleh mendahului argumen non-opsional dalam daftar argumen. |
Jenis ALL | {*} |
Menunjukkan bahwa variabel dapat mengambil jenis apa pun. |
Jenis UNKNOWN | {?} |
Menunjukkan bahwa variabel dapat mengambil jenis apa pun, dan compiler tidak boleh memeriksa jenis penggunaannya. |
Casting Jenis
Untuk mengonversi nilai ke jenis tertentu, gunakan sintaksis ini
/** @type {!MyType} */ (valueExpression)
Jenis Generik
Seperti Java, Closure Compiler mendukung jenis, fungsi, dan metode generik. Generik beroperasi pada objek dari berbagai jenis sambil mempertahankan keamanan jenis waktu kompilasi.
Anda dapat menggunakan generik untuk menerapkan koleksi umum yang menyimpan referensi ke objek dari jenis tertentu, dan algoritma umum yang beroperasi pada objek dari jenis tertentu.
Mendeklarasikan Jenis Generik
Jenis dapat dibuat generik dengan menambahkan anotasi @template
ke konstruktor jenis (untuk class) atau deklarasi antarmuka (untuk
antarmuka). Contoh:
/** * @constructor * @template T */ Foo = function() { ... };
Anotasi @template T
menunjukkan bahwa Foo
adalah jenis generik dengan satu jenis template, T
.
Jenis template T
dapat digunakan sebagai jenis dalam cakupan
definisi Foo
. Contoh:
/** @return {T} */ Foo.prototype.get = function() { ... }; /** @param {T} t */ Foo.prototype.set = function(t) { ... };
Metode get
akan menampilkan objek berjenis T
,
dan metode set
hanya akan menerima objek berjenis T
.
Membuat Instance Jenis Generik
Dengan menggunakan kembali contoh di atas, instance Foo
yang dibuat menggunakan template dapat dibuat dengan beberapa cara:
/** @type {!Foo<string>} */ var foo = new Foo(); var foo = /** @type {!Foo<string>} */ (new Foo());
Kedua pernyataan konstruktor di atas membuat instance Foo
yang jenis templatenya T
adalah string
. Compiler akan
memastikan bahwa panggilan ke metode foo
, dan akses ke
properti foo
, mematuhi jenis yang di-template. Contoh:
foo.set("hello"); // OK. foo.set(3); // Error - expected a string, found a number. var x = foo.get(); // x is a string.
Instance juga dapat diketik secara implisit oleh argumen konstruktornya.
Pertimbangkan jenis generik yang berbeda, Bar
:
/** * @param {T} t * @constructor * @template T */ Bar = function(t) { ... }; var bar = new Bar("hello"); // bar is a Bar<string>
Jenis argumen ke konstruktor Bar
disimpulkan
sebagai string
, dan sebagai hasilnya, instance bar
yang dibuat
disimpulkan sebagai Bar<string>
.
Beberapa Jenis Template
Generik dapat memiliki sejumlah jenis template. Class peta berikut memiliki dua jenis template:
/** * @constructor * @template Key, Val */ MyMap = function() { ... };
Semua jenis template untuk jenis generik harus ditentukan dalam anotasi
@template
yang sama, sebagai daftar yang dipisahkan koma. Urutan nama jenis template penting, karena anotasi jenis template akan menggunakan urutan untuk memasangkan jenis template dengan nilai. Contoh:
/** @type {MyMap<string, number>} */ var map; // Key = string, Val = number.
Invariansi Jenis Generik
Closure Compiler menerapkan pengetikan generik invarian. Artinya, jika konteks mengharapkan jenis Foo<X>
, Anda tidak dapat meneruskan jenis Foo<Y>
jika X
dan Y
adalah jenis yang berbeda, meskipun salah satunya adalah subjenis dari yang lain. Contoh:
/** * @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
Pewarisan Jenis Generik
Jenis generik dapat diwariskan, dan jenis template-nya dapat diperbaiki atau dipropagasi ke jenis yang mewarisi. Berikut adalah contoh jenis yang mewarisi dan memperbaiki jenis template supertype-nya:
/** * @constructor * @template T */ A = function() { ... }; /** @param {T} t */ A.prototype.method = function(t) { ... }; /** * @constructor * @extends {A<string>} */ B = function() { ... };
Dengan memperluas A<string>
, B
akan memiliki metode
method
yang mengambil parameter jenis string
.
Berikut adalah contoh jenis yang mewarisi jenis template superjenisnya:
/** * @constructor * @template U * @extends {A<U>} */ C = function() { ... };
Dengan memperluas A<U>
, instance C
yang dibuat dari template
akan memiliki metode method
yang mengambil parameter template
jenis U
.
Antarmuka dapat diimplementasikan dan diperluas dengan cara yang serupa, tetapi satu jenis tidak dapat mengimplementasikan antarmuka yang sama beberapa kali dengan jenis template yang berbeda. Contoh:
/** * @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
Fungsi dan Metode Generik
Mirip dengan jenis generik, fungsi dan metode dapat dibuat generik dengan menambahkan
anotasi @template
ke definisinya. Contoh:
/** * @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