diff --git a/packages/documentation/copy/id/Nightly Builds.md b/packages/documentation/copy/id/Nightly Builds.md new file mode 100644 index 000000000000..42d5e0aee5be --- /dev/null +++ b/packages/documentation/copy/id/Nightly Builds.md @@ -0,0 +1,80 @@ +--- +title: Nightly Builds +layout: docs +permalink: /id/docs/handbook/nightly-builds.html +oneline: Cara menggunakan nightly build TypeScript +translatable: true +--- + +_Nightly build_ dari _branch_ [master TypeScript](https://github.com/Microsoft/TypeScript/tree/master) diterbitkan pada tengah malam, di zona waktu PST ke npm. +Berikut adalah cara untuk mendapatkan versi ini dan cara menggunakannya. + +## Menggunakan npm + +```shell +npm install -g typescript@next +``` + +## Memperbarui IDE-mu untuk menggunakan _nightly builds_ + +Anda juga dapat memperbarui IDE-mu untuk menggunakan _nightly_ drop. +Pertama, Anda akan perlu untuk memasang package melalui npm. +Anda juga dapat memasang npm _package_ secara global atau pada direktori `node_modules` di dalam proyekmu. + +Pada tahap ini diasumsikan bahwa `typescript@next` sudah dipasang. + +### Visual Studio Code + +Perbarui `.vscode/settings.json` dengan cara berikut: + +```json +"typescript.tsdk": "/node_modules/typescript/lib" +``` + +Informasi lebih lanjut ada di [Dokumentasi VSCode](https://code.visualstudio.com/Docs/languages/typescript#_using-newer-typescript-versions). + +### Sublime Text + +Perbarui berkas `Settings - User` dengan cara berikut: + +```json +"typescript_tsdk": "/node_modules/typescript/lib" +``` + +Informasi lebih lanjut ada di [Dokumentasi pemasangan _Plugin_ TypeScript untuk Sublime Text](https://github.com/Microsoft/TypeScript-Sublime-Plugin#installation). + +### Visual Studio 2013 dan 2015 + +> Catatan: Sebagian besar perubahan tidak mengharuskan anda untuk memasang versi terbaru dari _plugin_ VS TypeScript. + +Saat ini, _Nightly build_ tidak menyertakan _plugin_ secara lengkap, tapi kami sedang mengupayakan untuk menerbitkan sebuah _installer_ di _nightly_. + +1. Unduh kode [VSDevMode.ps1](https://github.com/Microsoft/TypeScript/blob/master/scripts/VSDevMode.ps1) kode. + + > Lihat juga halaman wiki kami di [menggunakan berkas custom language service](https://github.com/Microsoft/TypeScript/wiki/Dev-Mode-in-Visual-Studio#using-a-custom-language-service-file). + +2. Melalui perintah PowerShell, jalankan: + +Untuk VS 2015: + +```posh +VSDevMode.ps1 14 -tsScript /node_modules/typescript/lib +``` + +Untuk VS 2013: + +```posh +VSDevMode.ps1 12 -tsScript /node_modules/typescript/lib +``` + +### IntelliJ IDEA (Mac) + +Masuk ke `Preferences` > `Languages & Frameworks` > `TypeScript`: + +> Versi TypeScript: Jika anda memasangnya dengan npm, maka akan ada di `/usr/local/lib/node_modules/typescript/lib` + +### IntelliJ IDEA (Windows) + +Masuk ke `File` > `Settings` > `Languages & Frameworks` > `TypeScript`: + +> Versi TypeScript: Jika anda memasangnya dengan npm, maka akan ada di `C:\Users\USERNAME\AppData\Roaming\npm\node_modules\typescript\lib` diff --git a/packages/documentation/copy/id/javascript/Creating DTS files From JS.md b/packages/documentation/copy/id/javascript/Creating DTS files From JS.md new file mode 100644 index 000000000000..22cf127b5cfc --- /dev/null +++ b/packages/documentation/copy/id/javascript/Creating DTS files From JS.md @@ -0,0 +1,87 @@ +--- +title: Membuat Berkas .d.ts dari berkas .js +layout: docs +permalink: /id/docs/handbook/declaration-files/dts-from-js.html +oneline: "Bagaimana cara menambahkan hasil d.ts ke proyek JavaScript" +translatable: true +--- + +[Dengan TypeScript 3.7](/docs/handbook/release-notes/typescript-3-7.html#--declaration-and---allowjs), TypeScript menambahkan dukungan untuk menghasilkan berkas .d.ts dari JavaScript menggunakan sintaks JSDoc. + +Pengaturan ini berarti Anda memiliki _editor_ yang mendukung TypeScript tanpa memindahkan proyek anda ke TypeScript, atau harus memelihara berkas .d.ts di basis kodemu. +TypeScript mendukung sebagian besar tag JSDoc, Anda bisa menemukannya [di referensi ini](/docs/handbook/type-checking-javascript-files.html#supported-jsdoc). + +## Menyiapkan proyekmu untuk menggunakan berkas .d.ts + +Untuk menambahkan pembuatan berkas .d.ts di proyekmu, Anda perlu melakukan empat langkah berikut: + +- Tambahkan TypeScript ke dependensi _dev_ Anda +- Tambahkan `tsconfig.json` untuk mengkonfigurasi TypeScript +- Jalankan kompilator TypeScript untuk menghasilkan berkas d.ts yang sesuai untuk berkas JS +- (_opsional_) Sunting package.json Anda untuk mereferensikan tipe + +### Menambahkan TypeScript + +Anda bisa mempelajari cara melakukan ini di [halaman instalasi](/download) kami. + +### TSConfig + +TSConfig adalah berkas jsonc yang mengkonfigurasi kedua _flag_ kompilator Anda, dan menyatakan di mana mencari berkas. +Dalam kasus ini, Anda menginginkan berkas seperti berikut: + +```json5 +{ + // Ubah ini agar sesuai dengan proyek Anda + include: ["src/**/*"], + + compilerOptions: { + // Memberi tahu TypeScript untuk membaca berkas JS, + // karena biasanya berkas tersebut diabaikan sebagai berkas sumber + allowJs: true, + // Hasilkan berkas d.ts + declaration: true, + // Proses kompilator ini seharusnya + // hanya mengeluarkan berkas d.ts + emitDeclarationOnly: true, + // Tipe harus masuk ke direktori ini. + // Menghapus ini akan menempatkan berkas .d.ts + // di sebelah berkas .js + outDir: "dist", + }, +} +``` + +Anda dapat mempelajari lebih lanjut tentang opsi di [referensi tsconfig](/reference). +Alternatif untuk menggunakan berkas TSConfig adalah CLI, ini adalah perilaku yang sama seperti perintah CLI. + +```sh +npx typescript src/**/*.js --declaration --allowJs --emitDeclarationOnly --outDir types +``` + +## Menjalankan kompilator + +Anda bisa mempelajari bagaimana melakukan ini di [halaman pemasangan](/download) TypeScript kami. +Anda perlu memastikan berkas-berkas ini disertakan dalam package Anda jika Anda memiliki berkas dalam `gitignore` proyek Anda. + +## Menyunting berkas package.json + +TypeScript mereplikasi resolusi _node_ untuk modul di `package.json`, dengan langkah tambahan untuk menemukan berkas .d.ts. +Secara garis besar, Pertama-tama resolusi akan memeriksa bagian `"types"` yang opsional, kemudian bidang `"main"`, dan terakhir akan mencoba `index.d.ts` di _root_. + +| Package.json | Location of default .d.ts | +| :------------------------ | :----------------------------- | +| No "types" field | checks "main", then index.d.ts | +| "types": "main.d.ts" | main.d.ts | +| "types": "./dist/main.js" | ./main/main.d.ts | + +Jika tidak ada, maka "main" akan digunakan + +| Package.json | Location of default .d.ts | +| :----------------------- | :------------------------ | +| No "main" field | index.d.ts | +| "main":"index.js" | index.d.ts | +| "main":"./dist/index.js" | ./dist/index.d.ts | + +## Tips + +Jika kamu suka menulis tes untuk berkas .d.ts, coba [tsd](https://github.com/SamVerschueren/tsd). diff --git a/packages/documentation/copy/id/javascript/Intro to JS with TS.md b/packages/documentation/copy/id/javascript/Intro to JS with TS.md new file mode 100644 index 000000000000..9239f5a93a9f --- /dev/null +++ b/packages/documentation/copy/id/javascript/Intro to JS with TS.md @@ -0,0 +1,70 @@ +--- +title: Memanfaatkan Typescript pada Proyek JS +layout: docs +permalink: /id/docs/handbook/intro-to-js-ts.html +oneline: Cara menambahkan pemeriksaan tipe data pada berkas JavaScript menggunakan TypeScript +translatable: true +--- + +Sistem tipe data di TypeScript memiliki tingkat keketatan yang berbeda saat bekerja dengan basis kode: + +- Sistem tipe data yang hanya berdasarkan pada inferensi dengan kode JavaScript +- Pengetikkan secara bertahap di JavaScript [melalui JSDoc](/docs/handbook/jsdoc-supported-types.html) +- Menggunakan `// @ts-check` di berkas JavaScript +- Kode TypeScript +- TypeScript dengan [`strict`](/tsconfig#strict) diaktifkan + +Setiap langkah mewakili tahapan sistem tipe yang lebih aman, tetapi tidak setiap proyek membutuhkan tingkat verifikasi seperti itu. + +## TypeScript dengan JavaScript + +Ini ketika _editor_-mu yang menggunakan TypeScript untuk menyediakan _tool_, seperti _auto-complete_, _jump to symbol_, dan _refactoring_, misalnya penamaan ulang. +Di [Homepage](/) tersedia daftar _editor_ yang memiliki plugin TypeScript. + +## Menyediakan Type Hints di JS melalui JSDoc + +Di berkas `.js`, tipe sering kali dapat diketahui. Namun ketika tipe tidak diketahui, mereka bisa ditentukan menggunakan sintaks JSDoc. + +Anotasi JSDoc diletakkan sebelum mendeklarasikan suatu hal. Seperti contoh berikut: + +```js twoslash +/** @type {number} */ +var x; + +x = 0; // OK +x = false; // OK?! +``` + +Anda dapat menemukan daftar lengkap mengenai dukungan pola JSDoc [di Tipe-tipe yang didukung JSDoc](/docs/handbook/jsdoc-supported-types.html) + +## `@ts-check` + +Baris terakhir dari contoh kode sebelumnya akan menimbulkan kesalahan dalam TypeScript, tetapi tidak secara bawaan dalam proyek JS. +Untuk mengaktifkan galat dalam berkas JavaScript-mu, tambahkan: `// @ ts-check` ke baris pertama dalam berkas`.js` Anda agar TypeScript dapat memeriksa kesalahan. + +```js twoslash +// @ts-check +// @errors: 2322 +/** @type {number} */ +var x; + +x = 0; // OK +x = false; // Not OK +``` + +Jika anda memiliki banyak berkas JavaScript yang ingin ditambahkan pemeriksaan galatnya, Anda bisa beralhir menggunakan [`jsconfig.json`](/docs/handbook/tsconfig-json.html). +Dengan begitu, Anda tidak perlu menambahkan `// @ts-nocheck` di tiap berkasnya. + +TypeScript mungkin memberikan galat yang Anda tidak sepakati. Pada kasus tersebut, Anda bisa membiarkan galat itu spesifik dibaris manapun dengan menambahkan `// @ts-ignore` atau `// @ts-expect-error`. + +```js twoslash +// @ts-check +/** @type {number} */ +var x; + +x = 0; // OK +// @ts-expect-error +x = false; // Not OK +``` + +Untuk mempelajari lebih lanjut bagaimana JavaScript diinterpretasi oleh TypeScript, Anda dapat membaca [Bagaimana TS Type Memeriksa JS](/docs/handbook/type-checking-javascript-files.html) diff --git a/packages/documentation/copy/id/javascript/JSDoc Reference.md b/packages/documentation/copy/id/javascript/JSDoc Reference.md new file mode 100644 index 000000000000..1bd7d961f2a4 --- /dev/null +++ b/packages/documentation/copy/id/javascript/JSDoc Reference.md @@ -0,0 +1,692 @@ +--- +title: Referensi JSDoc +layout: docs +permalink: /id/docs/handbook/jsdoc-supported-types.html +oneline: JSDoc apa yang didukung JavaScript dan TypeScript? +translatable: true +--- + +Dibawah ini adalah daftar anotasi yang didukung saat menggunakan JSDoc untuk menyediakan informasi di berkas Javscript. + +Perhatikan semua tag yang tidak secara eksplisit dicantumkan di bawah (seperti `@ async`) belum didukung. + +- `@type` +- `@param` (atau `@arg` atau `@argument`) +- `@returns` (atau `@return`) +- `@typedef` +- `@callback` +- `@template` +- `@class` (atau `@constructor`) +- `@this` +- `@extends` (atau `@augments`) +- `@enum` + +#### Ekstensi `class` + +- [Property Modifiers](#jsdoc-property-modifiers) `@public`, `@private`, `@protected`, `@readonly` + +Artinya biasanya sama, atau _superset_, dari arti _tag_ yang diberikan di [jsdoc.app](https://jsdoc.app). +Kode dibawah mendeskripsikan perbedaan dan beberapa contoh dari setiap _tag_-nya. + +**Catatan:** Anda bisa menggunakan [_playground_ untuk mengeksplor dukungan JSDoc](/play?useJavaScript=truee=4#example/jsdoc-support). + +## `@type` + +Anda dapat menggunakan _tag_ "@type" dan mereferensikan nama jenis (baik primitif, ditentukan dalam deklarasi TypeScript, atau dalam _tag_ "@typedef" JSDoc). +Anda dapat menggunakan sebagian besar jenis JSDoc dan jenis TypeScript apa pun, dari [yang paling dasar seperti `string`](/docs/handbookbasic-types.html) hingga [yang paling canggih, seperti jenis bersyarat](/docs/handbook/advanced-types.html). + +```js twoslash +/** + * @type {string} + */ +var s; + +/** @type {Window} */ +var win; + +/** @type {PromiseLike} */ +var promisedString; + +// Anda dapat menentukan Elemen HTML dengan properti DOM +/** @type {HTMLElement} */ +var myElement = document.querySelector(selector); +element.dataset.myData = ""; +``` + +`@type` dapat menetapkan tipe gabungan — misalnya, sesuatu bisa berupa _string_ atau _boolean_. + +```js twoslash +/** + * @type {(string | boolean)} + */ +var sb; +``` + +Perhatikan bahwa tanda kurung bersifat opsional untuk tipe gabungan. + +```js twoslash +/** + * @type {string | boolean} + */ +var sb; +``` + +Anda dapat menentukan tipe _array_ menggunakan berbagai sintaks: + +```js twoslash +/** @type {number[]} */ +var ns; +/** @type {Array.} */ +var nds; +/** @type {Array} */ +var nas; +``` + +Anda juga dapat menentukan tipe _literal_ objek. +Misalnya, objek dengan properti 'a' (_string_) dan 'b' (angka) menggunakan sintaks berikut: + +```js twoslash +/** @type {{ a: string, b: number }} */ +var var9; +``` + +Anda dapat menentukan objek seperti _map_ dan _array_ menggunakan index signature _string_ dan angka, menggunakan sintaks JSDoc standar atau sintaks TypeScript. + +```js twoslash +/** + * Objek map yang memetakan kunci string dan nilainya bertipe number. + * + * @type {Object.} + */ +var stringToNumber; + +/** @type {Object.} */ +var arrayLike; +``` + +Dua jenis sebelumnya sama dengan tipe TypeScript `{ [x: string]: number }` dan `{ [x: number]: any }`. Kompilator memahami kedua sintaks tersebut. + +Anda dapat menentukan jenis fungsi menggunakan sintaks TypeScript atau _Closure_: + +```js twoslash +/** @type {function(string, boolean): number} Closure syntax */ +var sbn; +/** @type {(s: string, b: boolean) => number} TypeScript syntax */ +var sbn2; +``` + +Atau anda dapat menggunakan type `Function` yang tidak ditentukan: + +```js twoslash +/** @type {Function} */ +var fn7; +/** @type {function} */ +var fn6; +``` + +Type lainnya dari _Closure_ juga berfungsi: + +```js twoslash +/** + * @type {*} - can be 'any' type + */ +var star; +/** + * @type {?} - unknown type (same as 'any') + */ +var question; +``` + +### Casts + +TypeScript meminjam sintaks _cast_ dari _Closure_. +Ini memungkinkan Anda mentransmisikan tipe ke tipe lain dengan menambahkan tag `@type` sebelum ekspresi dalam tanda kurung. + +```js twoslash +/** + * @type {number | string} + */ +var numberOrString = Math.random() < 0.5 ? "hello" : 100; +var typeAssertedNumber = /** @type {number} */ (numberOrString); +``` + +### Impor type + +Anda bisa juga mengimpor deklarasi dari berkas lain menggunakan impor tipe. +Sintaks ini khusus untuk TypeScript dan berbeda dari standar JSDoc: + +```js twoslash +// @filename: types.d.ts +export type Pet = { + name: string, +}; + +// @filename: main.js +/** + * @param p { import("./types").Pet } + */ +function walk(p) { + console.log(`Walking ${p.name}...`); +} +``` + +mengimpor tipe juga dapat digunakan di deklarasi tipe alias: + +```js twoslash +// @filename: types.d.ts +export type Pet = { + name: string, +}; +// @filename: main.js +// ---cut--- +/** + * @typedef { import("./types").Pet } Pet + */ + +/** + * @type {Pet} + */ +var myPet; +myPet.name; +``` + +Mengimpor tipe dapat digunakan untuk mendapatkan tipe nilai dari modul, jika Anda tidak mengetahui jenisnya, atau jika nilai tersebut memiliki tipe yang besar yang dapat mengganggu untuk diketik: + +```js twoslash +// @filename: accounts.d.ts +export const userAccount = { + name: "Name", + address: "An address", + postalCode: "", + country: "", + planet: "", + system: "", + galaxy: "", + universe: "", +}; +// @filename: main.js +// ---cut--- +/** + * @type {typeof import("./accounts").userAccount } + */ +var x = require("./accounts").userAccount; +``` + +## `@param` and `@returns` + +`@param` menggunakan jenis sintaks yang sama dengan `@type`, tapi dengan tambahan sebuah nama _parameter_. +_Parameter_ juga dapat dideklarasikan secara opsional dengan membungkus namanya menggunakan kurung siku: + +```js twoslash +// Parameter dapat dideklarasikan dalam berbagai bentuk sintaksis +/** + * @param {string} p1 - Parameter string. + * @param {string=} p2 - Opsional param (sintaks Closure) + * @param {string} [p3] - Opsional param lainnya (sintaks JSDoc). + * @param {string} [p4="test"] - Opsional param dengan nilai standar + * @return {string} Ini adalah hasilnya + */ +function stringsStringStrings(p1, p2, p3, p4) { + // MELAKUKAN +} +``` + +Demikian juga, untuk tipe kembalian suatu fungsi: + +```js twoslash +/** + * @return {PromiseLike} + */ +function ps() {} + +/** + * @returns {{ a: string, b: number }} - Dapat menggunakan '@returns' serta '@return' + */ +function ab() {} +``` + +## `@typedef`, `@callback`, and `@param` + +`@ty[edef` juga dapat digunakan untuk mendefinisikan tipe yang kompleks. +Sintaks yang bekerja dengan `@params`. + +```js twoslash +/** + * @typedef {Object} SpecialType - buat type baru bernama 'SpecialType' + * @property {string} prop1 - properti string dari SpecialType + * @property {number} prop2 - properti number dari SpecialType + * @property {number=} prop3 - properti number opsional dari SpecialType + * @prop {number} [prop4] - properti number opsional dari SpecialType + * @prop {number} [prop5=42] - properti number opsional dari SpecialType dengan nilai standar + */ + +/** @type {SpecialType} */ +var specialTypeObject; +specialTypeObject.prop3; +``` + +Anda bisa menggunakan `object` atau `Object` pada baris pertama. + +```js twoslash +/** + * @typedef {object} SpecialType1 - buat tipe baru bernama 'SpecialType' + * @property {string} prop1 - properti string dari SpecialType + * @property {number} prop2 - properti number dari SpecialType + * @property {number=} prop3 - opsional properti number dari SpecialType + */ + +/** @type {SpecialType1} */ +var specialTypeObject1; +``` + +`@params` memperbolehkan sintaks yang serupa untuk spesifikasi tipenya. +Perhatikan bahwa nama properti _nested_ harus diawali dengan nama _parameter_-nya: + +```js twoslash +/** + * @param {Object} options - Bentuknya sama dengan SpecialType di atas + * @param {string} options.prop1 + * @param {number} options.prop2 + * @param {number=} options.prop3 + * @param {number} [options.prop4] + * @param {number} [options.prop5=42] + */ +function special(options) { + return (options.prop4 || 1001) + options.prop5; +} +``` + +`@callback` mirip dengan `@typedef`, tetapi ini menetapkan tipe fungsi daripada tipe objek: + +```js twoslash +/** + * @callback Predicate + * @param {string} data + * @param {number} [index] + * @returns {boolean} + */ + +/** @type {Predicate} */ +const ok = (s) => !(s.length % 2); +``` + +Tentu saja, salah satu dari jenis ini dapat dideklarasikan menggunakan sintaks TypeScript dalam satu baris `@typedef`: + +```js +/** @typedef {{ prop1: string, prop2: string, prop3?: number }} SpecialType */ +/** @typedef {(data: string, index?: number) => boolean} Predicate */ +``` + +## `@template` + +Anda dapat mendeklarasikan fungsi generik dengan tag `@template`: + +```js twoslash +/** + * @template T + * @param {T} x - Parameter umum yang mengalir ke tipe kembalian + * @return {T} + */ +function id(x) { + return x; +} + +const a = id("string"); +const b = id(123); +const c = id({}); +``` + +Gunakan koma atau beberapa _tag_ untuk mendeklarasikan beberapa _parameter_ tipe: + +```js +/** + * @template T,U,V + * @template W,X + */ +``` + +Anda juga bisa menentukan batasan tipe sebelum nama _parameter_-nya. +Hanya _parameter_ tipe pertama dalam sebuah list yang dibatasi. + +```js twoslash +/** + * @template {string} K - K harus berupa string atau string literal + * @template {{ serious(): string }} Seriousalizable - harus memiliki method serious + * @param {K} key + * @param {Seriousalizable} object + */ +function seriousalize(key, object) { + // ???? +} +``` + +Mendeklarasikan kelas generik atau tipe yang tidak didukung. + +## Classes + +Kelas yang dapat dideklarasikan sebagai kelas ES6. + +```js twoslash +class C { + /** + * @param {number} data + */ + constructor(data) { + // tipe properti yang bisa diketahui + this.name = "foo"; + + // atau mengaturnya secara eksplisit + /** @type {string | null} */ + this.title = null; + + // atau hanya diberi anotasi, jika disetel di tempat lain + /** @type {number} */ + this.size; + + this.initialize(data); // Seharusnya galat, karena inisialisasi mengharapkan string + } + /** + * @param {string} s + */ + initialize = function (s) { + this.size = s.length; + }; +} + +var c = new C(0); + +// C seharusnya hanya dipanggil dengan yang baru, +// tetapi karena ini adalah JavaScript, ini +// diperbolehkan dan dianggap sebagai 'any'. +var result = C(1); +``` + +Mereka juga dapat dideklarasikan sebagai fungsi konstruktor, seperti yang dijelaskan di bagian selanjutnya: + +## `@constructor` + +Kompilator menyimpulkan fungsi konstruktor berdasarkan penetapan properti ini, tetapi Anda dapat membuat pemeriksaan lebih ketat dan saran lebih baik jika Anda menambahkan _tag_ `@constructor`: + +```js twoslash +// @checkJs +// @errors: 2345 2348 +/** + * @constructor + * @param {number} data + */ +function C(data) { + // tipe properti yang dapat diketahui + this.name = "foo"; + + // atau atur secara eksplisit + /** @type {string | null} */ + this.title = null; + + // atau hanya diberi anotasi, jika disetel di tempat lain + /** @type {number} */ + this.size; + + this.initialize(data); +} +/** + * @param {string} s + */ +C.prototype.initialize = function (s) { + this.size = s.length; +}; + +var c = new C(0); +c.size; + +var result = C(1); +``` + +> Catatan: Pesan galat hanya tampil di basis kode JS dengan [JSConfig](/docs/handbook/tsconfig-json.html) dan [`checkJS`](/tsconfig#checkJs) yang diaktifkan. + +Dengan `@constructor`, `this` diperiksa didalam fungsi konstruktor `C`, jadi anda akan mendapatkan saran untuk method `initialize` dan sebuah galat jika anda memasukkan sebuah angka. Editor-mu mungkin akan menampilkan peringatan jika memanggil `C` daripada mengkonstruksikannya. + +Sayangnya, ini berarti bahwa fungsi konstruktor yang juga dapat dipanggil tidak dapat menggunakan `@constructor`. + +## `@this` + +Kompilator biasanya dapat mengetahui tipe `this` ketika ia memiliki beberapa konteks untuk dikerjakan. Jika tidak, Anda dapat secara eksplisit menentukan jenis `this` dengan `@this`: + +```js twoslash +/** + * @this {HTMLElement} + * @param {*} e + */ +function callbackForLater(e) { + this.clientHeight = parseInt(e); // seharusnya baik-baik saja! +} +``` + +## `@extends` + +Ketika kelas JavaScript memperluas _base class_, tidak ada tempat untuk menentukan seharusnya menggunakan parameter tipe yang seperti apa. _Tag_ `@extends` menyediakan tempat untuk parameter jenis itu: + +```js twoslash +/** + * @template T + * @extends {Set} + */ +class SortableSet extends Set { + // ... +} +``` + +Perhatikan bahwa `@extends` hanya berfungsi dengan kelas. Saat ini, tidak ada cara untuk fungsi konstruktor memperluas kelas. + +## `@enum` + +Tag `@enum` memungkinkan Anda membuat _literal_ objek yang tipe anggotanya spesifik. Tidak seperti kebanyakan _literal_ objek di JavaScript, ini tidak mengizinkan anggota lain. + +```js twoslash +/** @enum {number} */ +const JSDocState = { + BeginningOfLine: 0, + SawAsterisk: 1, + SavingComments: 2, +}; + +JSDocState.SawAsterisk; +``` + +Perhatikan bahwa `@enum` sangat berbeda, dan jauh lebih sederhana daripada `enum` TypeScript. Namun, tidak seperti _enum_ TypeScript, `@enum` dapat memiliki tipe apa saja: + +```js twoslash +/** @enum {function(number): number} */ +const MathFuncs = { + add1: (n) => n + 1, + id: (n) => -n, + sub1: (n) => n - 1, +}; + +MathFuncs.add1; +``` + +## Lebih banyak contoh + +```js twoslash +class Foo {} +// ---cut--- +var someObj = { + /** + * @param {string} param1 - Dokumen tentang tugas properti + */ + x: function (param1) {}, +}; + +/** + * Seperti halnya dokumen tentang tugas variabel + * @return {Window} + */ +let someFunc = function () {}; + +/** + * Dan method kelas + * @param {string} greeting Salam untuk digunakan + */ +Foo.prototype.sayHi = (greeting) => console.log("Hi!"); + +/** + * Dan ekspresi arrow function + * @param {number} x - Pengganda + */ +let myArrow = (x) => x * x; + +/** + * Artinya, ini juga berfungsi untuk komponen fungsi stateless di JSX + * @param {{a: string, b: number}} test - Beberapa param + */ +var sfc = (test) =>
{test.a.charAt(0)}
; + +/** + * Parameter bisa menjadi konstruktor kelas, menggunakan sintaks Closure. + * + * @param {{new(...args: any[]): object}} C - Kelas untuk mendaftar + */ +function registerClass(C) {} + +/** + * @param {...string} p1 - A 'rest' arg (array) of strings. (treated as 'any') + */ +function fn10(p1) {} + +/** + * @param {...string} p1 - A 'rest' arg (array) of strings. (treated as 'any') + */ +function fn9(p1) { + return p1.join(); +} +``` + +## Pola yang diketahui TIDAK didukung + +Mengacu pada objek di _value space_ sebagai tipe yang tidak berfungsi, kecuali objek tersebut juga membuat tipe, seperti fungsi konstruktor. + +```js twoslash +function aNormalFunction() {} +/** + * @type {aNormalFunction} + */ +var wrong; +/** + * Gunakan 'typeof' sebagai gantinya: + * @type {typeof aNormalFunction} + */ +var right; +``` + +_Postfix_ sama dengan tipe properti dalam tipe _literal_ objek yang tidak menetapkan properti opsional: + +```js twoslash +/** + * @type {{ a: string, b: number= }} + */ +var wrong; +/** + * Gunakan postfix question pada nama properti sebagai gantinya: + * @type {{ a: string, b?: number }} + */ +var right; +``` + +Jenis _Nullable_ hanya memiliki arti jika `strictNullChecks` aktif: + +```js twoslash +/** + * @type {?number} + * With strictNullChecks: true -- number | null + * With strictNullChecks: false -- number + */ +var nullable; +``` + +Anda juga bisa menggunakan tipe gabungan: + +```js twoslash +/** + * @type {number | null} + * With strictNullChecks: true -- number | null + * With strictNullChecks: false -- number + */ +var unionNullable; +``` + +Tipe _non-nullable_ tidak memiliki arti dan diperlakukan seperti jenis aslinya: + +```js twoslash +/** + * @type {!number} + * Hanya bertipe number + */ +var normal; +``` + +Tidak seperti sistem tipe JSDoc, TypeScript hanya memungkinkan Anda untuk menandai tipe, apakah mengandung null atau tidak. +Tidak ada non-nullability eksplisit - jika strictNullChecks aktif, `number` tidak dapat dinihilkan. +Jika tidak aktif, maka `number` adalah nullable. + +### _Tag_ yang tidak didukung + +TypeScript mengabaikan semua _tag_ JSDoc yang tidak didukung. + +_Tag_ berikut memiliki isu terbuka untuk mendukungnya: + +- `@const` ([issue #19672](https://github.com/Microsoft/TypeScript/issues/19672)) +- `@inheritdoc` ([issue #23215](https://github.com/Microsoft/TypeScript/issues/23215)) +- `@memberof` ([issue #7237](https://github.com/Microsoft/TypeScript/issues/7237)) +- `@yields` ([issue #23857](https://github.com/Microsoft/TypeScript/issues/23857)) +- `{@link …}` ([issue #35524](https://github.com/Microsoft/TypeScript/issues/35524)) + +## Extensi kelas JS + +### _Modifier Property_ JSDoc + +Dari TypeScript 3.8 dan seterusnya, Anda dapat menggunakan JSDoc untuk mengubah properti kelas. Pertama adalah pengubah aksesibilitas: `@public`,`@private`, dan `@protected`. +Tag ini bekerja persis seperti `public`,`private`, dan `protected`, masing-masing berfungsi di TypeScript. + +```js twoslash +// @errors: 2341 +// @ts-check + +class Car { + constructor() { + /** @private */ + this.identifier = 100; + } + + printIdentifier() { + console.log(this.identifier); + } +} + +const c = new Car(); +console.log(c.identifier); +``` + +- `@public` ini berarti properti dapat diakses dari mana saja. +- `@private` berarti bahwa properti hanya dapat digunakan di dalam kelas yang memuatnya. +- `@protected` berarti bahwa properti hanya dapat digunakan di dalam kelas penampung, dan semua subkelas turunan, tetapi tidak pada instance kelas penampung yang berbeda. + +Selanjutnya, kita juga telah menambahkan _modifier_ `@readonly` untuk memastikan bahwa sebuah properti hanya dapat di-_write_ selama inisialisasi. + +```js twoslash +// @errors: 2540 +// @ts-check + +class Car { + constructor() { + /** @readonly */ + this.identifier = 100; + } + + printIdentifier() { + console.log(this.identifier); + } +} + +const c = new Car(); +console.log(c.identifier); +``` diff --git a/packages/documentation/copy/id/project-config/Configuring Watch.md b/packages/documentation/copy/id/project-config/Configuring Watch.md new file mode 100644 index 000000000000..568b9f637930 --- /dev/null +++ b/packages/documentation/copy/id/project-config/Configuring Watch.md @@ -0,0 +1,66 @@ +--- +title: Mengkonfigurasi Watch +layout: docs +permalink: /id/docs/handbook/configuring-watch.html +oneline: Cara mengkonfigurasi mode watch TypeScript +translatable: true +--- + +Kompilator mendukung konfigurasi cara mengawasi berkas dan direktori menggunakan kompilator _flags_ di TypeScript 3.8+, dan variabel _environment_. + +## Latar Belakang + +Implementasi `--watch` dari _compiter_ bergantung pada penggunaan `fs.watch` dan `fs.watchFile` yang disediakan oleh _node_, kedua metode ini memiliki kelebihan dan kekurangan. + +`fs.watch` menggunakan berkas _system event_ untuk memberi tahu perubahan dalam berkas/direktori. Tetapi ini bergantung pada OS dan notifikasi tidak sepenuhnya dapat diandalkan dan tidak berfungsi seperti yang diharapkan pada banyak OS. Juga mungkin ada batasan jumlah _watch_ yang dapat dibuat, misalnya linux dan kami dapat melakukannya dengan cukup cepat dengan program yang menyertakan banyak berkas. Tetapi karena ini menggunakan berkas _system event_, tidak banyak siklus CPU yang terlibat. Kompilator biasanya menggunakan `fs.watch` untuk melihat direktori (misalnya. Direktori sumber disertakan oleh berkas konfigurasi, direktori di mana resolusi modul gagal, dll.) Ini dapat menangani ketepatan yang hilang dalam memberi tahu tentang perubahan. Tetapi memantau secara rekursif hanya didukung pada Windows dan OSX. Artinya kita membutuhkan sesuatu untuk menggantikan sifat rekursif di OS lain. + +`fs.watchFile` menggunakan polling dan karenanya melibatkan siklus CPU. Tetapi ini adalah mekanisme yang paling andal untuk mendapatkan pembaruan status berkas/direktori. Kompilator biasanya menggunakan `fs.watchFile` untuk melihat berkas sumber, berkas konfigurasi dan berkas yang hilang (referensi berkas hilang) yang berarti penggunaan CPU bergantung pada jumlah berkas dalam program. + +## Konfigurasi berkas _watching_ menggunakan `tsconfig.json` + +```json tsconfig +{ + // Beberapa opsi kompilator umumnya + "compilerOptions": { + "target": "es2020", + "moduleResolution": "node" + // ... + }, + + // BARU: Opsi untuk memantau berkas/direktori + "watchOptions": { + // Gunakan native berkas system events untuk berkas dan direktori + "watchFile": "useFsEvents", + "watchDirectory": "useFsEvents", + + // Dapatkan pembaruan berkas + // ketika terdapat update yang besar. + "fallbackPolling": "dynamicPriority" + } +} +``` + +Anda dapat membacanya lebih lanjut di [catatan rilis](/docs/handbook/release-notes/typescript-3-8.html#better-directory-watching-on-linux-and-watchoptions). + +## Konfigurasi berkas _watching_ menggunakan variabel environment `TSC_WATCHFILE` + + +Opsi | Deskripsi +-----------------------------------------------|---------------------------------------------------------------------- +`PriorityPollingInterval` | Gunakan `fs.watchFile` tetapi gunakan _interval polling_ yang berbeda untuk berkas sumber, berkas konfigurasi, dan berkas yang hilang +`DynamicPriorityPolling` | Gunakan antrian dinamis di mana dalam berkas yang sering dimodifikasi akan memiliki _interval_ yang lebih pendek dan berkas yang tidak diubah akan lebih jarang diperiksa +`UseFsEvents` | Gunakan `fs.watch` untuk memanfaatkan _system event_ berkas (tetapi mungkin tidak akurat pada OS yang berbeda) untuk mendapatkan pemberitahuan terhadap perubahan/pembuatan/penghapusan berkas. Perhatikan bahwa beberapa OS misalnya. linux memiliki batasan jumlah pengamatan dan jika gagal melakukan pengamatan menggunakan `fs.watch`, maka pengamatan akan dilakukan dengan `fs.watchFile` +`UseFsEventsWithFallbackDynamicPolling` | Opsi ini mirip dengan `UseFsEvents` kecuali jika gagal memantau menggunakan `fs.watch`, pengawasan dilakukan melalui antrean _polling_ dinamis (seperti dijelaskan dalam `DynamicPriorityPolling`) +`UseFsEventsOnParentDirectory` | Opsi ini mengawasi direktori induk dari berkas dengan `fs.watch` (menggunakan berkas _system event_) sehingga menjadi rendah pada CPU tetapi dengan keakuratan yang rendah. +standar (tanpa menspesifikkan nilainya) | Jika variabel environment `TSC_NONPOLLING_WATCHER` di-set ke true, maka akan mengawasi direktori induk dari berkas (seperti `UseFsEventsOnParentDirectory`). Jika tidak, akan menggunakan `fs.watchFile` dengan `250ms` sebagai waktu tunggu untuk berkas apa pun. + +## Mengonfigurasi pengawasan direktori menggunakan variabel _environment_ `TSC_WATCHDIRECTORY` + +Pemantauan direktori pada platform yang tidak mendukung pemantau direktori rekursif secara _native_ di _node_, maka akan menggunakan opsi yang berbeda, yang dipilih oleh`TSC_WATCHDIRECTORY`. Perlu dicatat bahwa, _platform_ yang mendukung pemantauan direktori secara rekursif (misalnya Windows), nilai dari variabel environment tersebut akan diabaikan. + + +Opsi | Deskripsi +-----------------------------------------------|---------------------------------------------------------------------- +`RecursiveDirectoryUsingFsWatchFile` | Gunakan `fs.watchFile` untuk mengawasi direktori dan direktori anak yang merupakan _polling watch_ (menggunakan siklus CPU) +`RecursiveDirectoryUsingDynamicPriorityPolling`| Gunakan antrian polling dinamis untuk mengumpulkan perubahan pada direktori dan sub direktori. +_default_ (tidak ada nilai yang ditentukan) | Gunakan `fs.watch` untuk memantau direktoru dan sub direktorinya diff --git a/packages/documentation/copy/id/reference/Decorators.md b/packages/documentation/copy/id/reference/Decorators.md new file mode 100644 index 000000000000..6cd8e38de1a2 --- /dev/null +++ b/packages/documentation/copy/id/reference/Decorators.md @@ -0,0 +1,571 @@ +--- +title: Decorators +layout: docs +permalink: /id/docs/handbook/decorators.html +oneline: Ringkasan Dekorator TypeScript +translatable: true +--- + +## Pengenalan + +Dengan pengenalan Kelas-kelas yang ada di TypeScript dan ES6, sekarang ada skenario tertentu yang memerlukan fitur tambahan untuk mendukung anotasi atau modifikasi kelas dan anggota kelas. +_Decorators_ menyediakan cara untuk menambahkan anotasi-anotasi dan sebuah sintaks pemrogragaman meta untuk deklarasi kelas dan anggota kelas. +_Decorators_ ada pada [stage 2 proposal](https://github.com/tc39/proposal-decorators) untuk JavaScript dan juga tersedia pada TypeScript sebagai fitur eksperimental. + +> CATATAN  _Decorators_ adalah fitur eksperimental yang mungkin dapat berubah ketika dirilis nanti. + +Untuk mengaktifkan _Decorators_ eksperimental, anda harus menambahkan opsi `experimentalDecorators` ke baris perintah atau ke berkas `tsconfig.json`. + +**_Command Line_**: + +```shell +tsc --target ES5 --experimentalDecorators +``` + +**tsconfig.json**: + +```json tsconfig +{ + "compilerOptions": { + "target": "ES5", + "experimentalDecorators": true + } +} +``` + +## _Decorator_ + +_Decorator_ adalah jenis deklarasi khusus yang dapat dilampirkan ke [deklarasi kelas](#class-decorators), [method](#method-decorators), [accessor](#accessor-decorators), [property](#property-decorators), atau [parameter](#parameter-decorators). +_Decorators_ menggunakan bentuk `@expression`, dimana `expression` harus mengevaluasi fungsi yang akan dipanggil saat proses dengan informasi tentang deklarasi yang didekorasi. + +Sebagai contoh, ada decorator `@sealed` yang mungkin kita akan menuliskan fungsi `sealed` sebagai berikut: + +```ts +function sealed(target) { + // lakukan sesuatu dengan 'target' ... +} +``` + +> CATATAN  Anda dapat melihat contoh lengkapnya di [Decorator Kelas](#class-decorators). + +## _Decorator Factories_ + +Jika kita ingin menyesuaikan penerapan _decorator_ pada sebuah deklarasi, kita dapat menuliskan sebuah _decorator factory_. _Decorator Factory_ adalah sebuah fungsi yang mengembalikan ekspresi yang akan dipanggil oleh _decorator_ ketika proses. + +Kita dapat menuliskan _decorator factory_ seperti berikut: + +```ts +function color(value: string) { + // ini adalah decorator factory + return function (target) { + // ini adalah decorator + // lakukan sesuatu dengan 'target' dan 'value'... + }; +} +``` + +> CATATAN  Anda dapat melihat contoh lengkap dari penggunaan _decorator factory_ di [_Method Decorators_](#method-decorators) + +## Komposisi _Decorator_ + +Lebih dari satu _decorator_ dapat diterapkan pada sebuah deklarasi, seperti contoh berikut: + +- Penerapan dengan satu baris: + + ```ts + @f @g x + ``` + +- Penerapan lebih dari satu baris: + + ```ts + @f + @g + x + ``` + +Ketika lebih dari satu _decorator_ diterapkan ke sebuah deklarasi, evaluasi yang dilakukan mirip seperti [fungsi komposisi pada matematika](http://wikipedia.org/wiki/Function_composition). Pada model ini, ketika mengkomposisikan fungsi _f_ dan _g_, maka akan menjadi (_f_ ∘ _g_)(_x_) yang sama dengan _f_(_g_(_x_)). + +Dengan demikian, langkah-langkah berikut dilakukan saat mengevaluasi beberapa _decorator_ pada satu deklarasi di TypeScript: + +1. Ekspresi untuk setiap _decorator_ dievaluasi dari atas ke bawah. +2. Hasilnya kemudian disebut sebagai fungsi dari bawah ke atas. + +JIka kita menggunakan [_decorator factories_](#decorator-factories), kita dapat mengamati urutan evaluasi ini dengan contoh berikut: + +```ts +function f() { + console.log("f(): evaluated"); + return function ( + target, + propertyKey: string, + descriptor: PropertyDescriptor + ) { + console.log("f(): called"); + }; +} + +function g() { + console.log("g(): evaluated"); + return function ( + target, + propertyKey: string, + descriptor: PropertyDescriptor + ) { + console.log("g(): called"); + }; +} + +class C { + @f() + @g() + method() {} +} +``` + +Yang akan mencetak keluaran ini ke _console_: + +```shell +f(): evaluated +g(): evaluated +g(): called +f(): called +``` + +## Evaluasi _Decorator_ + +Ada urutan yang jelas tentang bagaimana _decorator_ diterapkan ke berbagai deklarasi yang ada di dalam kelas: + +1. _Parameter Decorators_, diikuti oleh _Method_, _Accessor_, atau _Property Decorators_ diterapkan untuk setiap anggota instance. +1. _Parameter Decorators_, diikuti oleh _Method_, _Accessor_, atau _Property Decorators_ diterapkan untuk setiap anggota statis. +1. _Parameter Dekorator_ diterapkan untuk konstruktor. +1. _Class Decorators_ diterapkan untuk kelas. + +## _Decorator_ Kelas + +_Class Decorator_ dideklarasikan tepat sebelum deklarasi kelas. +_Decorator_ kelas diterapkan ke konstruktor kelas dan dapat digunakan untuk mengamati, memodifikasi, atau mengganti definisi kelas. +_Decorator_ kelas tidak dapat digunakan dalam berkas deklarasi, atau dalam konteks ambien lainnya (seperti pada kelas `deklarasi`). + +Ekspresi untuk _decorator_ kelas akan dipanggil sebagai fungsi pada waktu proses, dengan konstruktor kelas yang didekorasi sebagai satu-satunya argumennya. + +Jika _decorator_ kelas mengembalikan nilai, deklarasi kelas akan diganti dengan fungsi konstruktor yang disediakan. + +> CATATAN  Jika Anda memilih untuk mengembalikan fungsi konstruktor baru, Anda harus berhati-hati dalam mempertahankan prototipe asli. +> Logika yang menerapkan dekorator pada waktu proses **tidak akan** melakukannya untukmu. + +Berikut ini adalah contoh _decorator_ kelas (`@sealed`) yang diterapkan ke kelas _`Greeter`_: + +```ts +@sealed +class Greeter { + greeting: string; + constructor(message: string) { + this.greeting = message; + } + greet() { + return "Hello, " + this.greeting; + } +} +``` + +Kita dapat mendefinisikan _decorator_ `@sealed` menggunakan deklarasi fungsi berikut: + +```ts +function sealed(constructor: Function) { + Object.seal(constructor); + Object.seal(constructor.prototype); +} +``` + +Ketika `@sealed` dijalankan, itu akan menyegel konstruktor dan prototipenya. + +Selanjutnya kita memiliki contoh bagaimana menimpa konstruktor. + +```ts +function classDecorator( + constructor: T +) { + return class extends constructor { + newProperty = "new property"; + hello = "override"; + }; +} + +@classDecorator +class Greeter { + property = "property"; + hello: string; + constructor(m: string) { + this.hello = m; + } +} + +console.log(new Greeter("world")); +``` + +## Method Decorators + +_Method Decorator_ dideklarasikan tepat sebelum deklarasi _method_. +Dekorator diterapkan ke _Property Descriptor_ untuk method, yang dapat digunakan untuk mengamati, memodifikasi, atau mengganti definisi _method_. +_Method Decorator_ tidak dapat digunakan dalam berkas deklarasi, saat kelebihan beban, atau dalam konteks ambien lainnya (seperti dalam kelas `declare`). + +Ekspresi untuk _method decorator_ akan dipanggil sebagai fungsi pada waktu proses, dengan tiga argumen berikut: + +1. Bisa memiliki fungsi konstruktor kelas untuk anggota statis, atau prototipe kelas untuk anggota _instance_. +2. Nama anggota. +3. The _Property Descriptor_ untuk anggota. + +> CATATAN  _Property Descriptor_ akan menjadi `undefined` jika target skripmu dibawah `ES5`. + +Jika _method decorator_ mengembalikan sebuah nilai, maka akan digunakan sebagai _Property Descriptor_ untuk method. + +> CATATAN  Nilai yang dikembalikan akan dibiarkan, jika target kodemu dibawah `ES5`. + +Berikut adalah contoh penerapan _method decorator_ (`@enumerable`) ke method yang ada pada kelas _`Greeter`_: + +```ts +class Greeter { + greeting: string; + constructor(message: string) { + this.greeting = message; + } + + @enumerable(false) + greet() { + return "Hello, " + this.greeting; + } +} +``` + +Kita dapat mendefinisikan _decorator_ `@enumerable` menggunakan fungsi deklarasi berikut: + +```ts +function enumerable(value: boolean) { + return function ( + target: any, + propertyKey: string, + descriptor: PropertyDescriptor + ) { + descriptor.enumerable = value; + }; +} +``` + +_Decorator_ `@enumerable(false)` disini adalah sebuah [_decorator factory_](#decorator-factories). +Ketika _decorator_ `@enumerable(false)` dipanggil, ia akan merubah _`enumerable`_ properti dari properti _descriptor_. + +## _Decorator_ Aksesor + +Sebuah _Accessor Decorator_ dideklarasikan tepat sebelum sebuah deklarasi aksesor. +_Decorator_ aksesor diterapkan ke _Property Descriptor_ untuk aksesor dan dapat digunakan untuk mengamati, memodifikasi, atau mengganti definisi aksesor. +_Decorator_ aksesor tidak dapat digunakan dalam deklarasi berkas, atau dalam konteks ambien lainnya (seperti dalam kelas `declare`). + +> CATATAN  TypeScript melarang penerapan _decorator_ ke aksesor `get` dan `set` untuk _single_ member. +> Sebaliknya, semua _decorator_ untuk anggota harus diterapkan ke pengakses pertama yang ditentukan dalam urutan dokumen. +> Ini karena _decorator_ berlaku untuk _Property Descriptor_, yang menggabungkan aksesor `get` dan `set`, bukan setiap deklarasi secara terpisah. + +Ekspresi untuk _decorator_ pengakses akan dipanggil sebagai fungsi pada waktu proses, dengan tiga argumen berikut: + +1. Bisa memiliki fungsi konstruktor kelas untuk anggota statis, atau prototipe kelas untuk anggota _instance_. +2. Nama anggota. +3. The _Property Descriptor_ untuk anggota. + +> CATATAN  _Property Descriptor_ akan menjadi `undefined`, jika target skripmu dibawah `ES5`. + +Jika aksesor _decorator_ mengembalikan sebuah nilai, ia akan digunakan sebagai _Property Descriptor_ untuk anggota. + +> CATATAN  Nilai yang dikembalikan akan dibiarkan, jika target skripmu dibawah `ES5`. + +Berikut ada contoh penerapan aksesor _decorator_ (`@configurable`) ke anggota kelas _`Point`_: + +```ts +class Point { + private _x: number; + private _y: number; + constructor(x: number, y: number) { + this._x = x; + this._y = y; + } + + @configurable(false) + get x() { + return this._x; + } + + @configurable(false) + get y() { + return this._y; + } +} +``` + +Kita dapat mendefinisikan _decorator_ `@configurable` menggunakan deklarasi fungsi berikut: + +```ts +function configurable(value: boolean) { + return function ( + target: any, + propertyKey: string, + descriptor: PropertyDescriptor + ) { + descriptor.configurable = value; + }; +} +``` + +## _Property Decorators_ + +Sebuah _Property Decorator_ dideklarasikan tepat sebelum deklarasi properti. +_Property Decorator_ tidak dapat digunakan dalam deklarasi berkas, atau dalam konteks ambien lainnya (seperti dalam kelas `declare`). + +Ekspresi untuk properti decorator akan dipanggil sebagai fungsi pada waktu proses, dengan dua argumen berikut: + +1. Dapat berupa fungsi konstruktor kelas untuk anggota statis, atau prototipe kelas untuk anggota _instance_. +2. Nama anggota. + +> CATATAN  _Property Descriptior_ tidak menyediakan sebuah argumen untuk properti _decorator_ karena bergantung tentang bagaimana properti _decorator_ diinisialisasi pada TypeScript. +> Ini karena, saat ini tidak ada mekanisme untuk mendeskripsikan sebuah _instance_ properti ketika mendefinisikan anggota dari sebuah prototipe, dan tidak ada cara untuk mengamati atau memodifikasi _initializer_ untuk properti. Dan nilai kembalian juga akan dibiarkan. +> Sehingga, sebuah properti _decorator_ hanya bisa digunakan untuk mengamati properti dengan nama yang spesifik, yang telah dideklarasikan pada sebuah kelas. + +Kita dapat menggunakan informasi tersebut untuk memantau properti metadata, seperti pada contoh berikut: + +```ts +class Greeter { + @format("Hello, %s") + greeting: string; + + constructor(message: string) { + this.greeting = message; + } + greet() { + let formatString = getFormat(this, "greeting"); + return formatString.replace("%s", this.greeting); + } +} +``` + +Kemudian, kita dapat mendefinisikan _decorator_ `@format` dan fungsi `getFormat` dengan menggunakan deklarasi fungsi berikut: + +```ts +import "reflect-metadata"; + +const formatMetadataKey = Symbol("format"); + +function format(formatString: string) { + return Reflect.metadata(formatMetadataKey, formatString); +} + +function getFormat(target: any, propertyKey: string) { + return Reflect.getMetadata(formatMetadataKey, target, propertyKey); +} +``` + +_Decorator_ `@format("Hello, %s")` disini adalah sebuah [decorator factory](#decorator-factories). +Ketika `@format("Hello, %s")` dipanggil, ia akan menambahkan properti metadata menggunakan fungsi `Reflect.metadata` dari pustaka `reflect-metadata`. +Ketika `getFormat` dipanggil, ia akan membaca format dari nilai _metadata_-nya. + +> CATATAN  Contoh ini membutuhkan pustaka `reflect-metadata`. +> Lihat [Metadata](#metadata) untuk informasi lebih lanjut mengenai pustaka `reflect-metadata`. + +## _Parameter Decorators_ + +_Parameter Decorator_ dideklarasikan tepat sebelum a parameter dideklarasikan. +_Parameter decorator_ diterapkan ke fungsi konstruktor pada kelas atau saat deklarasi _method_. +_Parameter decorator_ tidak dapat digunakan dalam deklarasi berkas, overload, atau dalam konteks ambien lainnya (seperti dalam kelas `declare`). + +Ekspresi untuk _parameter decorator_ akan dipanggil sebagai fungsi pada waktu proses, dengan tiga argumen berikut: + +1. Dapat berupa fungsi konstruktor kelas untuk anggota statis, atau prototipe kelas untuk anggota _instance_. +2. Nama anggota. +3. Indeks ordinal dari parameter dalam daftar parameter fungsi. + +> CATATAN  Sebuah _parameter decorator_ hanya bisa digunakan untuk mengamati sebuah parameter yang telah dideklarasikan pada sebuah method. + +Nilai kembalian dari _parameter decorator_ akan dibiarkan. + +Berikut adalah contoh penggunaan _parameter decorator_ (`@required`) pada anggota kelas `Greeter`: + +```ts +class Greeter { + greeting: string; + + constructor(message: string) { + this.greeting = message; + } + + @validate + greet(@required name: string) { + return "Hello " + name + ", " + this.greeting; + } +} +``` + +Kemudian, kita dapat mendefinisikan _decorator_ `@required` dan `@validate` menggunakan deklarasi fungsi berikut: + +```ts +import "reflect-metadata"; + +const requiredMetadataKey = Symbol("required"); + +function required( + target: Object, + propertyKey: string | symbol, + parameterIndex: number +) { + let existingRequiredParameters: number[] = + Reflect.getOwnMetadata(requiredMetadataKey, target, propertyKey) || []; + existingRequiredParameters.push(parameterIndex); + Reflect.defineMetadata( + requiredMetadataKey, + existingRequiredParameters, + target, + propertyKey + ); +} + +function validate( + target: any, + propertyName: string, + descriptor: TypedPropertyDescriptor +) { + let method = descriptor.value; + descriptor.value = function () { + let requiredParameters: number[] = Reflect.getOwnMetadata( + requiredMetadataKey, + target, + propertyName + ); + if (requiredParameters) { + for (let parameterIndex of requiredParameters) { + if ( + parameterIndex >= arguments.length || + arguments[parameterIndex] === undefined + ) { + throw new Error("Missing required argument."); + } + } + } + + return method.apply(this, arguments); + }; +} +``` + +_Decorator_ `@required` menambahkan entri metadata yang menandakan bahwa parameter tersebut diperlukan. +_Decorator_ `@validate` kemudian akan memvalidasi semua argumen yang ada, sebelum _method_-nya dijalankan. + +> CATATAN  Contoh ini memerlukan pustaka `reflect-metadata` +> Lihat [Metadata](#metadata) untuk informasi lebih lanjut mengenai pustaka `reflect-metadata`. + +## _Metadata_ + +Beberapa contoh menggunakan pustaka `reflect-metadata` yang menambahkan _polyfill_ untuk [API metadata eksperimental](https://github.com/rbuckton/ReflectDecorators). +Pustaka ini belum menjadi bagian dari standar ECMAScript (JavaScript). +Namun, ketika decorator secara resmi diadopsi sebagai bagian dari standar ECMAScript, ekstensi ini akan diusulkan untuk diadopsi. + +Anda dapat memasang pustaka ini melalui npm: + +```shell +npm i reflect-metadata --save +``` + +TypeScript menyertakan dukungan eksperimental untuk menghadirkan jenis _metadata_ tertentu untuk deklarasi yang memiliki _decorator_. +Untuk mengaktifkan dukungan eksperimental ini, Anda harus mengatur opsi kompilator `emitDecoratorMetadata` baik pada baris perintah atau di `tsconfig.json` Anda: + +**_Command Line_**: + +```shell +tsc --target ES5 --experimentalDecorators --emitDecoratorMetadata +``` + +**tsconfig.json**: + +```json tsconfig +{ + "compilerOptions": { + "target": "ES5", + "experimentalDecorators": true, + "emitDecoratorMetadata": true + } +} +``` + +Ketika diaktifkan, selama pustaka `reflect-metadata` di-_import_, informasi jenis _design-time_ tambahan akan diekspos saat _runtime_. + +Kita dapat melihat action pada contoh berikut: + +```ts +import "reflect-metadata"; + +class Point { + x: number; + y: number; +} + +class Line { + private _p0: Point; + private _p1: Point; + + @validate + set p0(value: Point) { + this._p0 = value; + } + get p0() { + return this._p0; + } + + @validate + set p1(value: Point) { + this._p1 = value; + } + get p1() { + return this._p1; + } +} + +function validate( + target: any, + propertyKey: string, + descriptor: TypedPropertyDescriptor +) { + let set = descriptor.set; + descriptor.set = function (value: T) { + let type = Reflect.getMetadata("design:type", target, propertyKey); + if (!(value instanceof type)) { + throw new TypeError("Invalid type."); + } + set.call(target, value); + }; +} +``` + +Kompilator TypeScript akan memasukkan informasi jenis _design-time_ menggunakan _decorator_ `@Reflect.metadata`. +Anda dapat menganggapnya setara dengan TypeScript berikut: + +```ts +class Line { + private _p0: Point; + private _p1: Point; + + @validate + @Reflect.metadata("design:type", Point) + set p0(value: Point) { + this._p0 = value; + } + get p0() { + return this._p0; + } + + @validate + @Reflect.metadata("design:type", Point) + set p1(value: Point) { + this._p1 = value; + } + get p1() { + return this._p1; + } +} +``` + +> CATATAN  _Decorator_ metadata adalah fitur _experimental_ dan mungkin dapat menyebabkan gangguan pada rilis di masa mendatang. diff --git a/packages/documentation/copy/id/reference/Iterators and Generators.md b/packages/documentation/copy/id/reference/Iterators and Generators.md new file mode 100644 index 000000000000..9a7c28dcbb25 --- /dev/null +++ b/packages/documentation/copy/id/reference/Iterators and Generators.md @@ -0,0 +1,90 @@ +--- +title: Iterators dan Generators +layout: docs +permalink: /id/docs/handbook/iterators-and-generators.html +oneline: Bagaimana Iterator dan Generator bekerja di TypeScript +translatable: true +--- + +## Iterasi + +Sebuah objek dapat dilakukan perulangan jika memiliki properti [`Symbol.iterator`](Symbols.html#symboliterator). +Beberapa tipe bawaan seperti `Array`, `Map`, `Set`, `String`, `Int32Array`, `Uint32Array`, etc. sudah memiliki properti `Symbol.iterator`. +Fungsi `Symbol.iterator` pada sebuah objek, bertanggungjawab untuk mengembalikan _list_ nilai-nilai untuk menjalankan iterasi. + +## Pernyataan `for..of` + +`for..of` mengulang objek yang dapat diulang dengan cara memanggil properti `Symbol.iterator` pada objek tersebut. +Berikut ini _loop_ `for..of` sederhana pada sebuah _array_: + +```ts +let someArray = [1, "string", false]; + +for (let entry of someArray) { + console.log(entry); // 1, "string", false +} +``` + +### Pernyataan `for..of` vs `for..in` + +Baik pernyataan `for..of` dan `for..in` akan mengiterasi _list_; yang membedakan antara keduanya adalah `for..in` akan mengembalikan daftar _keys_ dari objek tersebut, sedangkan `for..of` mengembalikan daftar _values_ properti numeric dari objek yang diiterasi. + +Berikut adalah contoh implementasi dari perbedaan keduanya: + +```ts +let list = [4, 5, 6]; + +for (let i in list) { + console.log(i); // "0", "1", "2", +} + +for (let i of list) { + console.log(i); // "4", "5", "6" +} +``` + +Perbedaan lainnya adalah `for..in` bekerja pada objek apapun; ini berfungsi sebagai cara untuk memeriksa properti pada objek tersebut. +Di sisi lain, `for..of` tertarik pada nilai dari objek yang dapat diulang. Objek bawaan seperti `Map` dan`Set` mengimplementasikan properti `Symbol.iterator` yang memungkinkan akses ke nilai yang disimpan. + +```ts +let pets = new Set(["Cat", "Dog", "Hamster"]); +pets["species"] = "mammals"; + +for (let pet in pets) { + console.log(pet); // "species" +} + +for (let pet of pets) { + console.log(pet); // "Cat", "Dog", "Hamster" +} +``` + +### Pembuatan kode + +#### Menargetkan ES5 dan ES3 + +Ketika menargetkan ke engine ES5 atau ES3, _iterator_ hanya membolehkan nilai bertipe `Array`. +Akan terjadi galat jika `for..of` melakukan perulangan pada nilai yang bukan Array, bahkan jika nilai non _Array_ tersebut memiliki properti `Symbol.iterator`. + +Kompilator akan menghasilkan perulangan `for` sederhana untuk `for..of`, misalnya: + +```ts +let numbers = [1, 2, 3]; +for (let num of numbers) { + console.log(num); +} +``` + +akan menghasilkan: + +```js +var numbers = [1, 2, 3]; +for (var _i = 0; _i < numbers.length; _i++) { + var num = numbers[_i]; + console.log(num); +} +``` + +#### Menargetkan ECMAScript 2015 dan yang lebih tinggi + +Ketika menargetkan ke _engine_ ECMAScript 2015, kompilator akan membuat perulangan `for..of` untuk menargetkan implementasi _iterator_ bawaan di mesin. diff --git a/packages/documentation/copy/id/reference/JSX.md b/packages/documentation/copy/id/reference/JSX.md new file mode 100644 index 000000000000..8735d3296331 --- /dev/null +++ b/packages/documentation/copy/id/reference/JSX.md @@ -0,0 +1,442 @@ +--- +title: JSX +layout: docs +permalink: /id/docs/handbook/jsx.html +oneline: Menggunakan JSX dengan TypeScript +translatable: true +--- + +[JSX](https://facebook.github.io/jsx/) adalah sebuah sintaks tertanam, yang seperti XML. +Ini dimaksudkan untuk diubah menjadi JavaScript yang _valid_, meskipun semantik dari transformasi itu khusus untuk implementasi. +JSX menjadi populer dengan kerangka kerja [React](https://reactjs.org/), tetapi sejak itu juga melihat implementasi lain. +TypeScript mendukung _embeding_, pemeriksaan tipe, dan mengkompilasi JSX secara langsung ke JavaScript. + +## Dasar Penggunaan + +Untuk menggunakan JSX, Anda harus melakukan dua hal berikut: + +1. Penamaan berkas dengan ekstensi `.tsx` +2. Mengaktifkan opsi `jsx` + +TypeScript memiliki tiga jenis mode JSX: `preserve`, `react`, dan `react-native`. +Mode tersebut hanya berlaku untuk _stage_, sedangkan untuk pemeriksaan tipe, hal itu tidak berlaku. +Mode `preserve` akan mempertahankan JSX sebagai bagian dari _output_ untuk selanjutnya digunakan oleh langkah transformasi lain (mis. [Babel](https://babeljs.io/)). +Selain itu, _output_-nya akan memiliki ekstensi berkas `.jsx`. +Mode `react` akan mengeluarkan`React.createElement`, tidak perlu melalui transformasi JSX sebelum digunakan, dan outputnya akan memiliki ekstensi berkas `.js`. +Mode `react-native` sama dengan `pertahankan` yang mempertahankan semua JSX, tetapi hasilnya justru akan memiliki ekstensi berkas `.js`. + +| Mode | Input | Output | Berkas Output Extension | +| -------------- | --------- | ---------------------------- | ----------------------- | +| `preserve` | `
` | `
` | `.jsx` | +| `react` | `
` | `React.createElement("div")` | `.js` | +| `react-native` | `
` | `
` | `.js` | + +Anda dapat menetapkan mode ini menggunakan _flag_ baris perintah `--jsx` atau opsi yang sesuai di berkas [tsconfig.json](/docs/handbook/tsconfig-json.html) Anda. + +> \*Catatan: Anda dapat menentukan fungsi _factory_ JSX yang akan digunakan saat menargetkan react JSX _emit_ dengan opsi `--jsxFactory` (nilai bawaan ke `React.createElement`) + +## Opeartor `as` + +Ingat bagaimana menulis penegasan tipe: + +```ts +var foo = bar; +``` + +Ini menegaskan variabel `bar` memiliki tipe `foo`. +Sejak TypeScript juga menggunakan kurung siku untuk penegasan tipe, mengkombinasikannya dengan sintaks JSX akan menimbulkan kesulitan tertentu. Hasilnya, TypeScript tidak membolehkan penggunaan kurung siku untuk penegasan tipe pada berkas `.tsx`. + +Karena sintaks diatas tidak bisa digunakan pada berkas `.tsx`, maka alternatif untuk penegasan tipe dapat menggunakan operator `as`. +Contohnya dapat dengan mudah ditulis ulang dengan operator `as`. + +```ts +var foo = bar as foo; +``` + +Operator `as` tersedia dikedua jenis berkas, `.ts` dan `.tsx`, dan memiliki perlakuan yang sama seperti penegasan tipe menggunakan kurung siku. + +## Pemeriksaan Tipe + +Urutan yang harus dimengerti mengenai pemeriksaan tipe di JSX, yaitu pertama Anda harus memahami perbedaan antara elemen intrinsik dan elemen berbasiskan nilai. Terdapat sebuah ekspresi `` dan `expr` yang mungkin mengacu pada suatu hal yang intrinsik pada suatu lingkungan (misalnya `div` atau `span` dalam lingkungan DOM) atau pada komponen custom yang telah Anda buat. +Ini penting karena dua alasan berikut: + +1. Untuk React, elemen intrinsik dianggap sebagai string (`React.createElement("div")`), sedangkan komponen yang Anda buat bukan (`React.createElement(MyComponent)`). +2. Type dari atribut yang dilewatkan ke elemen JSX seharusnya terlihat berbeda. + Atribut elemen intrinsik seharusnya diketahui _secara intrinsik_ sedangkan komponen akan seperti ingin untuk menentukan kumpulan atribut mereka sendiri. + +TypeScript menggunakan [beberapa convention yang dengan React](http://facebook.github.io/react/docs/jsx-in-depth.html#html-tags-vs.-react-components) untuk membedakannya. +Elemen intrinsik selalu dimulai dengan huruf kecil, dan elemen berbasiskan nilai selalu dimulai dengan huruf besar. + +## Elemen intrinsik + +Elemen intrinsik dicari pada _interface_ khusus, yaitu `JSX.IntrinsicElements`. +Standarnya, jika _interface_ ini tidak ditentukan, maka apapun yang terjadi dan elemen intrinsik tidak akan diperiksa tipenya. +Namun, jika _interface_ ini ada, maka nama elemen intrinsik akan dicari sebagai properti di _interface_ `JSX.IntrinsicElements`. +Contohnya: + +```ts +declare namespace JSX { + interface IntrinsicElements { + foo: any; + } +} + +; // ok +; // galat +``` + +Pada contoh diatas, `` akan berjalan dengan baik, tapi `` akan menghasilkan galat, karena `` tidak ditentukan pada _interface_ `JSX.IntrinsicElements`. + +> Catatan: Anda juga bisa menentukan _indexer_ untuk mendapatkan seluruh elemen bertipe string didalam `JSX.IntrinsicElements`, seperti berikut: + +```ts +declare namespace JSX { + interface IntrinsicElements { + [elemName: string]: any; + } +} +``` + +## Elemen Berbasiskan Nilai + +Elemen berbasiskan nilai akan dicari oleh _identifier_ yang ada pada sebuah _scope_. + +```ts +import MyComponent from "./myComponent"; + +; // ok +; // galat +``` + +Terdapat dua cara untuk mendefinisikan sebuah elemen berbasiskan nilai, yaitu: + +1. _Function Component_ (FC) +2. _Class Component_ + +Karena kedua jenis elemen berbasis nilai ini tidak dapat dibedakan satu sama lain dalam ekspresi JSX, maka pertama TS akan mencoba menyelesaikan ekspresi tersebut sebagai _Function Component_ menggunakan _overloading_. Jika proses berhasil, maka TS selesai menyelesaikan ekspresi ke deklarasinya. Jika gagal untuk menyelesaikan sebagai _Function Component_, maka TS kemudian akan mencoba untuk menyelesaikannya sebagai _Class Component_. Jika gagal, TS akan melaporkan kesalahan. + +### _Function Component_ + +Seperti namanya, komponen ini didefinisikan menggunakan fungsi JavaScript dimana argumen pertamanya adalah sebuah `props` objek. +TS memberlakukan bahwa tipe kembaliannya harus dapat diberikan ke `JSX.Element`. + +```ts +interface FooProp { + name: string; + X: number; + Y: number; +} + +declare function AnotherComponent(prop: {name: string}); +function ComponentFoo(prop: FooProp) { + return ; +} + +const Button = (prop: {value: string}, context: { color: string }) =>