Nominal Typing di Typescript

Jihad Dzikri Waspada
codewey
Published in
3 min readOct 6, 2018

Seperti yang kita ketahui, teknik type check yang digunakan Typescript adalah structural checking. Bahkan di level class pun masih structural check, agak berbeda dengan Flow yang menggunakan nominal check di level ini (https://flow.org/en/docs/lang/nominal-structural/#toc-nominal-typing). Sehingga code ini pun typechecked di Typescript:

Di beberapa bahasa pemrograman seperti Java, class A dan class B dianggap sesuatu yang berbeda, walaupun secara structural sama. Inilah yang dimaksud dengan nominal check atau nominal typing.

Nominal types akan sangat berguna untuk modelling data yang tidak pandang struktur. Misal seperti membedakan Celcius dengan Fahrenheit:

const fiveC: Celcius = 5;
const fiveF: Fahrenheit = 5;

yang walaupun sama-sama bertipe number, mereka tidaklah sama. 5℃ !== 5℉. Seperti yang pernah saya bahas di artikel sebelumnya:

And in fact, Phantom Type adalah salah satu cara untuk mencapai Nonimal Typing. Namun di artikel ini, saya akan propose solusi yang lebih general dari Phantom Type, yang bisa diterapkan di tipe data apapun. Nama umumnya adalah Branding.

Branding

Teknik branding ini sebenarnya sama persis seperti Phantom Type:

Brand Type

Jika kita coba membuat sebuah function yang menerima argument bertipe Celcius namun malah memberinya Fahrenheit, maka compiler akan komplain:

Berhasil! fiveC dan fiveF ter-model-kan pada saat compile time, sehingga tidak perlu khawatir akan “tertukar” saat run time. Code kita pun menjadi sangat expressive :)

Bila kita mampir sebentar ke internal compiler Typescript itu sendiri, kita bisa langsung melihat penggunaan nominal type ini.

Improvements

Kita bisa membuat improvements dari implementasi Brand<Name, Type> yang kita buat di atas. Karena pada praktiknya, implementasi di atas agak kaku:

const fiveC: Celcius = 5; // errorType '5' is not assignable to type 'Brand<"Celcius", number>'.
Type '5' is not assignable to type '{ _brand: "Celcius"; }'.

So, kita hanya perlu mengubah properti _brand menjadi optional:

Masih ada yang bisa di-improve btw. Kalau diperhatikan, key _brand, masih bisa diakses dari luar dan kita gak mau begitu supaya code tetap clean.

nope!

Caranya dengan menggunakan Symbol sebagai key-nya dan tidak meng-export key tersebut.

Sekarang key-nya menajdi tidak accessable ke user!

yes!

Done 🎉🎉🎉

BTW, saya pribadi lebih suka dengan term “new type” dibanding “brand”, mengambil keyword dari Haskell (https://wiki.haskell.org/Newtype):

Tapi ndak ada alasan spesifik kok, cuman preferensi 🙂

Kesimpulan

Tulisan ini saya rasa terlalu singkat, jadi disimpulkan sendiri aja ya 😁.

Clap if you find this article useful 👏🏻

Semoga bermanfaat! 🎉

--

--

Jihad Dzikri Waspada
codewey

Software Developer @Chordify, Utrecht. NOTE: Please navigate to https://jihadwaspada.com. I no longer write on Medium