Jenis Dan Antarmuka di TypeScript Beserta Contoh Penggunaan

TypeScript Jenis Dan Antarmuka Beserta Contoh Penggunaan

TypeScript, dengan kekayaan ekspresi tipenya, memberikan dukungan yang kuat untuk teknik-teknik pemrograman fungsional seperti komposisi dan kekekalan. Kekuatan ini diperkuat oleh dua cara utama dalam mendefinisikan tipe: menggunakan type dan interface. Memahami kapan dan bagaimana menggunakan keduanya dapat membantu mengoptimalkan desain kode dan mempertahankan keamanan tipe.

Tipe Dan Tipe Alias

Dalam TypeScript, konsep “tipe” berperan penting dalam memandu kita dalam mengelola berbagai jenis data yang kita kerjakan, semacam blueprint untuk struktur data kita.

Jenis Dasar: TypeScript menyediakan beberapa tipe dasar seperti string, boolean, number, array, tuple, dan enum, yang membantu kita mendefinisikan dan mengontrol struktur data secara eksplisit dan aman.

Tipe Alias: Di sisi lain, kita memiliki “tipe alias,” yang bisa kita anggap sebagai ‘nama panggilan’ atau referensi alternatif untuk tipe yang sudah ada. Tipe alias tidak menciptakan tipe baru; mereka hanya memberikan cara untuk merujuk tipe yang sama dengan nama yang berbeda, membuat kode lebih mudah untuk diikuti.

Misalnya, kita bisa mendefinisikan tipe alias untuk number sebagai MyNumber, sehingga setiap kali kita merujuk ke MyNumber, kita sebenarnya merujuk ke tipe number.

Read More

Kita juga dapat menggunakan tipe alias untuk menggabungkan atau menyusun tipe yang lebih kompleks, seperti struktur data untuk pengguna:

typescriptCopy codetype User = {
  name: string;
  age: number;
  email: string;
};

Perdebatan antara “tipe vs. antarmuka” seringkali muncul dalam konteks ini, tetapi sesungguhnya ini lebih tepatnya merupakan perbandingan antara “tipe alias vs. antarmuka”. Kedua pendekatan ini memiliki fungsionalitas yang serupa dalam banyak kasus namun juga memiliki perbedaan kunci dalam bagaimana dan kapan mereka harus digunakan, tergantung pada kebutuhan spesifik proyek atau preferensi pengkodean.

Antarmuka Di TypeScript

Di TypeScript, konsep antarmuka sangat penting dan berfungsi hampir seperti kontrak bagi objek. Antarmuka menentukan bahwa suatu objek harus memiliki set properti tertentu dengan tipe data yang spesifik. Hal ini memberikan struktur dan kejelasan dalam pemrograman, memastikan bahwa objek yang dibuat sesuai dengan definisi yang ditetapkan.

Misalnya, jika Anda mendefinisikan antarmaja untuk “Customer”, Anda mungkin mengharuskan setiap objek pelanggan memiliki “name” dan “address”:

typescriptCopy codeinterface Customer {
  name: string;
  address: string;
}

Dengan mendefinisikan antarmuka seperti ini, Anda memastikan bahwa setiap objek pelanggan yang Anda buat dalam kode Anda memenuhi kriteria ini.

Sementara itu, “type annotations” atau anotasi tipe sering digunakan untuk tujuan yang serupa. Meskipun anotasi tipe tidak selalu menciptakan struktur baru seperti antarmuka, mereka sangat berguna untuk menetapkan tipe data pada variabel, fungsi, dan lain-lain, sehingga menambah kejelasan dan keamanan tipe.

Baik menggunakan antarmuka atau anotasi tipe, keduanya merupakan alat yang berguna dalam TypeScript untuk membantu mengatur dan menjamin integritas tipe data dalam program Anda.

Perbedaan antara tipe dan antarmuka

Tipe dan antarmuka digunakan untuk menentukan struktur dan bentuk data khusus, namun keduanya memiliki beberapa perbedaan dalam perilaku dan penggunaan.

1. Tipe Primitif

Tipe primitif adalah tipe data dasar yang tersedia dalam TypeScript dan digunakan untuk merepresentasikan nilai-nilai sederhana seperti angka, string, boolean, null, dan undefined. Dalam TypeScript, kita bisa menggunakan dua pendekatan untuk bekerja dengan tipe primitif: menggunakan “type” atau “interface”.

Pertama, mari kita lihat bagaimana kita bisa menggunakan “type” untuk membuat alias untuk tipe primitif:

typescriptCopy codetype MyNumber = number;

Dalam contoh ini, kita membuat alias tipe MyNumber yang hanya merupakan sinonim untuk tipe primitif angka.

Namun, tidak seperti “type”, Anda tidak dapat secara langsung mendefinisikan tipe primitif menggunakan antarmuka. Tipe primitif seperti angka, string, dan boolean sudah ditentukan sebelumnya di TypeScript dan tidak memerlukan definisi tambahan. Antarmuka lebih cocok digunakan untuk mendefinisikan struktur yang lebih kompleks daripada sekadar tipe primitif.

Jadi, sementara Anda dapat menggunakan “type” untuk membuat alias untuk tipe primitif, Anda tidak dapat melakukannya dengan antarmuka karena tipe primitif sudah didefinisikan secara bawaan dalam TypeScript.

2. Tipe MyUnionType

Tipe MyUnionType atau serikat pekerja, atau yang sering disebut sebagai tipe gabungan, adalah tipe data dalam TypeScript yang memungkinkan variabel memiliki salah satu dari beberapa tipe yang ditentukan. Dalam TypeScript, kita bisa menggunakan “type” untuk mendefinisikan tipe serikat pekerja:

typescriptCopy codetype MyUnionType = number | string;

Di sini, kita mendefinisikan tipe MyUnionType yang dapat berisi nilai angka atau string.

Namun, ketika menggunakan antarmuka, umumnya tidak lazim untuk langsung merepresentasikan tipe gabungan. Alih-alih, Anda harus menggunakan alias tipe untuk tujuan ini. Meskipun demikian, Anda dapat menggunakan tipe gabungan sebagai bagian dari definisi antarmuka yang lebih kompleks.

Jadi, sementara Anda dapat dengan mudah mendefinisikan tipe serikat pekerja menggunakan “type”, Anda mungkin tidak akan melakukannya secara langsung dengan antarmuka.

3. Tipe Fungsi

Tipe fungsi digunakan untuk mendefinisikan tipe data fungsi dalam TypeScript. Di sini, saya akan menjelaskan cara mendefinisikan tipe fungsi menggunakan “type” dan antarmuka:

1. Menggunakan “type” untuk mendefinisikan tipe fungsi:

type MyFunctionType = (arg1: number, arg2: string) => boolean;

Dalam contoh ini, kita mendefinisikan tipe MyFunctionType yang merepresentasikan sebuah fungsi. Fungsi ini mengambil dua argumen, yang pertama bertipe angka dan yang kedua bertipe string, dan mengembalikan nilai boolean.

2. Menggunakan antarmuka untuk mendefinisikan tipe fungsi:

typescriptCopy codeinterface MyFunctionInterface {
  (arg1: number, arg2: string): boolean;
}

Di sini, antarmuka MyFunctionInterface digunakan untuk mendefinisikan tipe fungsi yang sama. Ini adalah cara lain untuk menentukan tipe data fungsi dalam TypeScript.

Kedua pendekatan tersebut akan menciptakan tipe yang sama, yaitu tipe fungsi yang mengambil dua argumen (angka dan string) dan mengembalikan nilai boolean.

Penggabungan Pernyataan

Dalam TypeScript, Anda dapat menggabungkan pernyataan antarmuka dengan nama yang sama. Mari kita lihat bagaimana cara kerjanya:

typescriptCopy codeinterface Person {
  name: string;
}

interface Person {
  age: number;
}

Dalam contoh ini, kita memiliki dua pernyataan antarmuka dengan nama yang sama, yaitu Person. TypeScript akan secara otomatis menggabungkan kedua pernyataan ini menjadi satu antarmuka tunggal yang mencakup semua properti dari kedua pernyataan tersebut. Jadi, hasilnya akan menjadi:

typescriptCopy codeinterface Person {
  name: string;
  age: number;
}

Ini berarti antarmuka Person sekarang memiliki dua properti, yaitu name dengan tipe string dan age dengan tipe number.

Namun, penting untuk dicatat bahwa tipe alias tidak mendukung penggabungan deklarasi seperti ini. Jika Anda mencoba mendefinisikan alias tipe yang sama beberapa kali, TypeScript akan menghasilkan kesalahan. Jadi, dalam kasus tipe alias, Anda harus membuat deklarasi yang unik.

Ekstensi vs. Persilangan

Dalam TypeScript, Anda dapat memperluas antarmuka dengan menggunakan ekstensi atau membuat persilangan antara dua tipe. Mari kita bandingkan keduanya:

Menggunakan Ekstensi:

typescriptCopy codeinterface A { 
  propA: number; 
}

interface B extends A { 
  propB: string; 
}

Dalam contoh ini, antarmuka B meng-extend antarmuka A, yang berarti B mewarisi semua properti yang ada di A dan menambahkan properti propB yang baru.

Menggunakan Persilangan:

typescriptCopy codetype AB = A & { 
  propB: string; 
}

Di sini, kita menggunakan persilangan (&) untuk menggabungkan properti dari tipe A dengan properti baru propB untuk membuat tipe AB.

Kedua pendekatan ini memiliki hasil yang sama: sebuah tipe yang memiliki properti propA dari A dan properti propB yang baru. Namun, perbedaannya terletak pada cara pendeklarasiannya. Ekstensi lebih umum digunakan ketika Anda ingin mewarisi properti dari antarmuka yang ada, sementara persilangan berguna ketika Anda perlu menggabungkan properti dari dua tipe yang berbeda secara eksplisit.

Mengatasi Konflik

Konflik saat memperluas dapat diatasi dengan memastikan properti dengan nama yang sama memiliki tipe yang cocok. Jika tidak, TypeScript akan menghasilkan kesalahan. Berikut adalah cara menangani konflik semacam itu:

Penanganan Konflik Saat Memperluas:

typescriptCopy codeinterface A { 
  commonProp: number; 
}
interface B { 
  commonProp: string; 
}
interface AB extends A, B { 
  commonProp: number | string; // Penanganan konflik dengan menetapkan tipe yang cocok
}

Dalam contoh di atas, kita memperbaiki konflik dengan menetapkan tipe properti commonProp pada antarmuka AB menjadi number | string.

Menangani Jenis Tupel:

typescriptCopy codetype MyTupleType = [number, string];
const tuple: MyTupleType = [42, "hello"];

Di sini, kita mendefinisikan tipe tupel menggunakan tipe dan kemudian membuat variabel dari tipe tupel tersebut.

Gunakan Antarmuka:

typescriptCopy codeinterface MyTupleInterface {
  0: number;
  1: string;
}
const tuple: MyTupleInterface = [42, "hello"];

Anda juga dapat menggunakan antarmuka untuk menentukan tipe tupel, dan penggunaannya tetap sama. Dalam kasus ini, kita mendefinisikan antarmuka dengan angka indeks sebagai nama propertinya, yang sesuai dengan posisi elemen dalam tupel.

Kapan Menggunakan Tipe vs. Antarmuka

Pilih antarmuka saat Anda perlu menggabungkan atau memodifikasi struktur yang sudah ada, terutama saat bekerja dengan perpustakaan atau membuatnya sendiri. Antarmuka memungkinkan Anda untuk dengan mudah menggabungkan atau memperluas deklarasi, membuatnya lebih efisien untuk berinteraksi dengan kode yang ada. Selain itu, antarmuka biasanya lebih mudah dibaca dan dipahami, terutama jika Anda mempertimbangkan pendekatan pemrograman berorientasi objek.

Di sisi lain, gunakan jenis saat Anda membutuhkan fitur yang lebih canggih. Sistem tipe TypeScript menyediakan alat canggih seperti tipe bersyarat, generik, pelindung tipe, dan lainnya. Fitur-fitur ini memberi Anda kontrol lebih besar atas jenis Anda, membantu Anda membuat aplikasi yang kuat dan kuat secara tipe. Antarmuka tidak dapat memberikan tingkat kontrol dan kemampuan ini.

Secara umum, Anda dapat menggunakan tipe atau antarmuka sesuai dengan preferensi pribadi Anda. Namun, tipe alias lebih umum digunakan dalam situasi berikut:

  • Ketika Anda perlu memberi nama baru untuk tipe data dasar seperti ‘String’ atau ‘Number’.
  • Saat mendefinisikan tipe yang lebih kompleks seperti gabungan, tupel, atau fungsi.
  • Ketika Anda menggunakan fungsi overload.
  • Saat memanfaatkan fitur lanjutan seperti tipe yang dipetakan, tipe bersyarat, atau pelindung tipe.

Tipe umumnya lebih fleksibel dan ekspresif, menawarkan berbagai fitur canggih yang tidak dapat disaingi oleh antarmuka. Selain itu, TypeScript terus memperluas kemampuannya, memberi Anda lebih banyak alat untuk bekerja dengan jenis data dalam kode Anda.

Contoh Penggunaan

Kami menggunakan alias tipe untuk secara otomatis menghasilkan metode pengambil untuk tipe objek, yang tidak dapat Anda lakukan dengan antarmuka:

typescriptCopy codetype Client = {
    name: string;
    address: string;
}

type Getters<T> = {
    [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};

type clientType = Getters<Client>;
// Hasilnya adalah: 
// {
//     getName: () => string;
//     getAddress: () => string;
// }

Dengan menggunakan tipe yang dipetakan, literal templat, dan operator ‘keyof’, kita membuat tipe yang secara otomatis menghasilkan metode pengambil untuk tipe objek apa pun.

Selain itu, banyak pengembang lebih suka menggunakan tipe karena cocok dengan paradigma pemrograman fungsional.

Kekayaan ekspresi tipe di TypeScript memudahkan bekerja dengan konsep fungsional seperti komposisi dan kekekalan sambil menjaga keamanan tipe.

Kesimpulan

Dalam TypeScript, kita memiliki dua konsep utama untuk mendefinisikan tipe data: tipe dan antarmuka.

Tipe adalah cara untuk memberikan alias atau nama alternatif untuk tipe data yang ada, yang membantu dalam membuat kode lebih mudah dibaca dan dipahami. Mereka terutama digunakan untuk mendefinisikan tipe data dasar, seperti angka, string, boolean, serta tipe data yang lebih kompleks, seperti tipe gabungan, tupel, atau fungsi. Tipe juga mendukung fitur-fitur lanjutan seperti tipe yang dipetakan, tipe bersyarat, dan pelindung tipe. Mereka ideal digunakan dalam skenario di mana Anda membutuhkan kontrol ekspresif yang tinggi atas tipe Anda.

Antarmuka, di sisi lain, adalah seperangkat aturan atau persyaratan yang harus diikuti oleh suatu objek. Mereka digunakan untuk mendefinisikan struktur objek dan sering kali digunakan untuk menggabungkan atau memperluas deklarasi, membuatnya lebih mudah untuk bekerja dengan kode yang ada. Antarmuka memberikan fleksibilitas dan kemudahan dalam memahami kode, terutama dalam konteks pemrograman berorientasi objek.

Pilihan antara tipe dan antarmuka seringkali tergantung pada preferensi pribadi dan kebutuhan proyek. Tipe umumnya lebih cocok untuk skenario di mana Anda membutuhkan fitur yang lebih canggih atau kontrol yang lebih besar atas tipe Anda, sementara antarmuka lebih mudah digunakan dalam situasi di mana Anda bekerja dengan struktur objek yang ada atau ingin membuat perpustakaan yang mudah dipahami oleh pengguna lain.

Related posts

Leave a Reply

Your email address will not be published. Required fields are marked *