Catatan: Halaman ini sudah tidak berlaku. Daftar lengkapnya dikelola di https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler
Ringkasan
Closure Compiler dapat menggunakan informasi jenis data tentang variabel JavaScript untuk memberikan peringatan dan pengoptimalan yang lebih baik. Namun, JavaScript tidak dapat 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 telah berbeda. Kini, anotasi 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
Closure Compiler 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 serta kesalahan lainnya.
Tabel ini hanya menyertakan tag yang memengaruhi perilaku Closure Compiler. Untuk informasi tentang tag JSDoc lainnya, lihat dokumentasi Toolkit JSDoc.
Tag | Deskripsi |
---|---|
@abstract
|
Menandai metode sebagai abstrak. Serupa dengan menyetel metode ke
Compiler menghasilkan peringatan jika metode yang ditandai
dengan /** @abstract */ foo.MyClass.prototype.abstractMethod = function() {}; |
@const
|
Menandai variabel sebagai hanya baca. Compiler dapat
menerapkan variabel Deklarasi jenis bersifat opsional.
Compiler 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 flag --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 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 merupakan sekumpulan 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
|
Memberikan kode ini /** @export */ foo.MyPublicClass.prototype.myPublicMethod = function() { // ... };
saat dijalankan dengan flag 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 penerapan pewarisan, lihat fungsi Library Closure Contoh: /** * Immutable empty node list. * @constructor * @extends {goog.ds.BasicNodeList} */ goog.ds.EmptyNodeList = function() { ... }; |
@final
|
Menunjukkan bahwa class ini tidak diizinkan untuk diperluas. Untuk metode, menunjukkan bahwa tidak ada subclass yang diizinkan untuk menggantikan 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 menghasilkan 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 di deklarasi properti eksternal.
Properti memiliki jenis yang dideklarasikan, tetapi Anda dapat menetapkan jenis apa pun tanpa
peringatan. Saat mengakses properti, Anda mendapatkan kembali nilai dari jenis yang dideklarasikan. Misalnya, /** * @type {string} * @implicitCast */ Element.prototype.innerHTML; |
@inheritDoc
|
Menunjukkan bahwa metode atau properti subclass
secara 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 jenis yang diperlukan. Setiap class yang mengimplementasikan antarmuka
harus mengimplementasikan semua metode dan properti yang ditentukan pada
prototipe
antarmuka. Lihat
Compiler memverifikasi bahwa antarmuka tidak dipakai. 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 tertentu lainnya. Anotasi ini hanya boleh muncul di literal objek.
Perhatikan bahwa nama dalam tanda kurung kurawal bukan nama jenis seperti
dalam anotasi lainnya. Ini adalah nama objek. Properti ini memberikan nama
objek yang dipinjamkan properti.
Misalnya, Dokumen JS 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) bertahan saat kompilasi tidak berubah. Jeda baris 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 ini 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 ini 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 paket pribadi. Hanya kode dalam direktori yang sama
yang dapat mengakses nama yang ditandai sebagai
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 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; }Untuk parameter yang merupakan pola destrukturisasi, Anda dapat menggunakan nama apa pun yang merupakan ID JS yang valid, setelah anotasi jenis. /** * @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 dari konstruktor yang ditandai Contoh: /** * Handlers that are listening to this logger. * @private {Array<Function>} */ this.handlers_ = []; |
@protected
|
Menunjukkan bahwa anggota atau properti dilindungi.
Properti bertanda
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 metode dan definisi fungsi.
Tag
Atau, Anda dapat menganotasi jenis nilai yang ditampilkan
(lihat fungsi
Jika fungsi yang tidak ada dalam ekstensi 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 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 ditampilkan oleh fungsi. Pemeriksa jenis saat ini tidak menggunakan informasi ini. Informasi ini hanya digunakan untuk mengetahui apakah fungsi yang dideklarasikan di file ekstern memiliki efek samping. Contoh: /** * @throws {DOMException} */ DOMApplicationCache.prototype.swapCache = function() { ... }; |
@type
|
Mengidentifikasi jenis variabel, properti, atau ekspresi. Tag Saat mendeklarasikan variabel atau parameter fungsi,
Anda dapat menulis anotasi jenis secara 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 level 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 dari 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.
Semakin banyak jenis yang Anda tentukan dalam kode, semakin banyak pengoptimalan yang dapat dilakukan oleh compiler dan semakin banyak kesalahan yang dapat ditangkapnya.
Compiler menggunakan anotasi ini untuk memeriksa program Anda.
Perhatikan bahwa Closure Compiler tidak berjanji akan dapat mengetahui jenis setiap ekspresi dalam program Anda. Cara ini sebaik mungkin dengan melihat cara variabel digunakan, dan pada anotasi jenis yang dilampirkan pada deklarasinya. Kemudian, algoritme ini menggunakan sejumlah algoritme inferensi jenis untuk
mencari tahu jenis ekspresi sebanyak mungkin. Beberapa
algoritme ini sederhana ("jika x adalah angka, dan kita melihat
y = x;
, maka y adalah angka"). Beberapa parameter lebih tidak langsung ("jika parameter pertama
f didokumentasikan sebagai callback yang harus mengambil angka,
dan kita melihat f(function(x) { /** ... */ });
, maka x harus
berupa angka").
Nama Operator | Contoh Sintaksis | Deskripsi |
---|---|---|
Nama Jenis |
{boolean} {Window} {goog.ui.Menu}
|
Menentukan nama jenis. |
Jenis Aplikasi |
{Array<string>} Array string.
|
Membuat parameter jenis dengan serangkaian argumen jenis. Mirip dengan generik Java. |
Jenis Penyatuan |
{(number|boolean)} Angka atau boolean. Catat tanda kurung, yang diperlukan. |
Menunjukkan bahwa nilai mungkin memiliki tipe A ATAU tipe 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 dari jenis yang ditentukan. Kurung kurawal adalah bagian dari sintaksis jenis. Misalnya, untuk
menunjukkan |
Jenis nullable |
{?number} Angka atau null .
|
Menunjukkan bahwa nilai adalah jenis A atau Semua jenis objek adalah nullable secara default, terlepas dari apakah objek tersebut dideklarasikan dengan operator Nullable atau tidak. Jenis objek didefinisikan sebagai apa pun, kecuali fungsi, string, angka, atau boolean. Untuk membuat jenis objek non-nullable, gunakan operator Non-nullable. |
Jenis non-nullable |
{!Object} Objek, tetapi tidak pernah berupa nilai null .
|
Menunjukkan bahwa nilai adalah jenis A dan bukan null. Fungsi dan semua jenis nilai (boolean, angka, dan string) bersifat non-nullable secara default, baik dideklarasikan maupun tidak dengan operator Non-nullable. Untuk membuat nilai atau jenis fungsi nullable, gunakan operator Nullable. |
Jenis Fungsi |
{function(string, boolean)} Fungsi yang menggunakan dua parameter (string dan boolean), dengan nilai return yang tidak diketahui. |
Menentukan fungsi dan jenis parameter fungsi. |
Jenis Fungsi yang Ditampilkan |
{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 menggunakan 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 baru goog.ui.Menu saat dipanggil dengan kata kunci 'new'. |
Menentukan jenis konstruktor yang dibuat. |
Parameter variabel |
{function(string, ...number): number} Fungsi yang menggunakan satu parameter (string), lalu angka variabel parameter yang harus berupa angka. |
Menunjukkan bahwa jenis fungsi mengambil angka variabel parameter, dan menentukan jenis untuk parameter variabel. |
Parameter variabel (dalam anotasi @param )
|
@param {...number} var_args Angka variabel parameter ke fungsi yang dianotasi. |
Menunjukkan bahwa fungsi yang dianotasi menerima jumlah parameter yang bervariasi, dan menentukan jenis untuk parameter variabel. |
Parameter opsional dalam anotasi @param
|
@param {number=} opt_argument Parameter opsional jenis 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 nullable opsional dan satu angka opsional sebagai argumen. |
Menunjukkan bahwa argumen dalam jenis fungsi bersifat opsional. Argumen opsional dapat dihilangkan dari panggilan fungsi. Argumen opsional tidak dapat mendahului argumen non-opsional dalam daftar argumen. |
Jenis ALL | {*} |
Menunjukkan bahwa variabel dapat mengambil jenis apa pun. |
Jenis TIDAK DIKETAHUI | {?} |
Menunjukkan bahwa variabel dapat menerima jenis apa pun, dan compiler tidak boleh memeriksa penggunaan variabel tersebut. |
Transmisi Jenis
Untuk mentransmisikan nilai ke jenis tertentu, gunakan sintaksis ini
/** @type {!MyType} */ (valueExpression)Tanda kurung di sekitar ekspresi selalu diperlukan.
Jenis Generik
Sama seperti Java, Closure Compiler mendukung jenis, fungsi, dan metode generik. Generik beroperasi pada objek dari berbagai jenis sekaligus mempertahankan keamanan jenis waktu kompilasi.
Anda dapat menggunakan generik untuk mengimplementasikan koleksi umum yang menyimpan referensi ke objek dari jenis tertentu, dan algoritme umum yang beroperasi melalui objek dari jenis tertentu.
Mendeklarasikan Jenis Umum
Suatu jenis dapat dibuat umum 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 dengan jenis T
.
Membuat Instance Jenis Generik
Dengan menggunakan contoh di atas, instance template Foo
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
memberlakukan bahwa panggilan ke metode foo
, dan akses ke
properti foo
, mengikuti jenis 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 lain, 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 akibatnya, instance
yang dibuat bar
disimpulkan sebagai Bar<string>
.
Beberapa Jenis Template
Generik dapat memiliki berapa pun 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 pengurutan untuk memasangkan jenis template dengan nilai. Contoh:
/** @type {MyMap<string, number>} */ var map; // Key = string, Val = number.
Invarian Jenis Umum
Closure Compiler memberlakukan 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 jenis lainnya. 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 diwarisi, dan jenis template-nya dapat diperbaiki atau disebarkan ke jenis pewarisan. Berikut adalah contoh jenis pewarisan yang memperbaiki jenis template supertipenya:
/** * @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 menggunakan parameter jenis string
.
Berikut adalah contoh jenis pewarisan yang menyebarkan jenis template supertipenya:
/** * @constructor * @template U * @extends {A<U>} */ C = function() { ... };
Dengan memperluas A<U>
, instance template
C
akan memiliki metode method
yang menggunakan parameter jenis
template U
.
Antarmuka dapat diimplementasikan dan diperluas dengan cara yang sama, 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 Umum
Serupa 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