TypeScript - Penyekir

Hai, para pemrogram yang bersemangat! Hari ini, kita akan melangkah ke dalam dunia menarik TypeScript Decorators. Jangan khawatir jika Anda baru dalam pemrograman - saya akan memandu Anda melalui konsep ini secara langkah demi langkah, seperti yang telah saya lakukan bagi ribuan murid selama tahun-tahun mengajar. Jadi, mari kita masuk ke dalamnya!

TypeScript - Decorators

Apa Itu Decorators?

Sebelum kita melompat ke detilnya, mari kita mengerti apa itu decorators. Bayangkan Anda memiliki kue kering. Decorators seperti halnya topping, frosting, dan buah ceri di atasnya yang membuat kue Anda menjadi lebih istimewa. Dalam TypeScript, decorators menambah fungsi ekstra ke kelas, metode, properti, dan parameter Anda.

Menggunakan Decorators dalam TypeScript

Untuk mulai menggunakan decorators dalam TypeScript, Anda perlu mengaktifkan mereka dalam file tsconfig.json. Itu seperti menyalakan oven sebelum memanggang kue kering Anda!

{
"compilerOptions": {
"experimentalDecorators": true
}
}

Sintaks Decorator

Sekarang, mari kita lihat bagaimana kita menulis decorators. Itu lebih mudah daripada yang Anda pikirkan!

function simpleDecorator(target: any) {
console.log("Saya decorator sederhana!");
}

@simpleDecorator
class MyClass {
// Implementasi kelas
}

Dalam contoh ini, simpleDecorator seperti stiker yang kita tempelkan pada MyClass. Setiap kali kita menggunakan MyClass, itu akan mencatat "Saya decorator sederhana!" ke konsol.

Pabrik Decorator

kadang-kadang, kita ingin decorators kita dapat disesuaikan. Itu di mana pabrik decorator memasuki panggung. Mereka seperti mesin yang menghasilkan decorators berdasarkan spesifikasi kita.

function decoratorFactory(message: string) {
return function (target: any) {
console.log(message);
}
}

@decoratorFactory("Hai, saya decorator custom!")
class MyClass {
// Implementasi kelas
}

Di sini, decoratorFactory membuat decorator yang mencatat pesan custom kita.

Komposisi Decorator

Kita dapat menggunakan beberapa decorators pada satu target. Itu seperti menambahkan beberapa topping ke kue kering Anda!

function pertama() {
console.log("pertama(): pabrik dievaluasi");
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
console.log("pertama(): dipanggil");
};
}

function kedua() {
console.log("kedua(): pabrik dievaluasi");
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
console.log("kedua(): dipanggil");
};
}

class ExampleClass {
@pertama()
@kedua()
method() {}
}

Dalam kasus ini, decorators diterapkan dari bawah ke atas: kedua() kemudian pertama().

Mengapa Menggunakan Decorators?

Decorators sangat berguna untuk:

  1. Menambah metadata ke kode Anda
  2. Mengubah perilaku kelas dan metode
  3. Mengimplementasikan aspek dari Aspect-Oriented Programming
  4. Membuat kode yang dapat dipakai kembali dan mudah diterapkan ke kelas-kelas berbeda

Decorators Kelas

Decorator kelas diterapkan ke kontruktur kelas dan dapat digunakan untuk mengamati, mengubah, atau mengganti definisi kelas.

function sealed(constructor: Function) {
Object.seal(constructor);
Object.seal(constructor.prototype);
}

@sealed
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}

Dalam contoh ini, decorator @sealed menghindari modifikasi kelas Greeter setelah definisinya.

Decorators Metode

Decorator metode dapat digunakan untuk mengubah, mengamati, atau mengganti definisi metode.

function enumerable(value: boolean) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
descriptor.enumerable = value;
};
}

class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}

@enumerable(false)
greet() {
return "Hello, " + this.greeting;
}
}

Di sini, decorator @enumerable(false) membuat metode greet tidak dapat dienumerasi.

Decorators Akses

Decorator aksesor diterapkan ke property descriptor untuk akses dan dapat digunakan untuk mengamati, mengubah, atau mengganti definisi akses.

function configurable(value: boolean) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
descriptor.configurable = value;
};
}

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; }
}

Dalam contoh ini, decorator @configurable(false) membuat akses x dan y tidak dapat dikonfigurasi.

Decorators Properti

Decorator properti digunakan untuk mengamati, mengubah, atau mengganti definisi properti.

function format(formatString: string) {
return function (target: any, propertyKey: string): any {
let value = target[propertyKey];

const getter = function () {
return `${formatString} ${value}`;
};

const setter = function (newVal: string) {
value = newVal;
};

return {
get: getter,
set: setter,
enumerable: true,
configurable: true
};
};
}

class Greeter {
@format("Hello,")
greeting: string;
}

const greeter = new Greeter();
greeter.greeting = "World";
console.log(greeter.greeting); // Output: "Hello, World"

Di sini, decorator @format menambahkan prefiks ke properti greeting.

Decorators Parameter

Decorator parameter digunakan untuk mengamati, mengubah, atau mengganti definisi parameter.

function required(target: Object, propertyKey: string | symbol, parameterIndex: number) {
let existingRequiredParameters: number[] = Reflect.getOwnMetadata("required", target, propertyKey) || [];
existingRequiredParameters.push(parameterIndex);
Reflect.defineMetadata("required", existingRequiredParameters, target, propertyKey);
}

class Greeter {
greet(@required name: string) {
return "Hello " + name;
}
}

Dalam contoh ini, decorator @required menandai parameter name sebagai wajib.

Metode Decorator

Berikut adalah tabel yang menggabungkan jenis decorator yang berbeda dan metode mereka:

Jenis Decorator Metode
Decorator Kelas declare type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void;
Decorator Metode declare type MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;
Decorator Akses declare type AccessorDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;
Decorator Properti declare type PropertyDecorator = (target: Object, propertyKey: string | symbol) => void;
Decorator Parameter declare type ParameterDecorator = (target: Object, propertyKey: string | symbol, parameterIndex: number) => void;

Dan itu adalah! Kita telah melihat dasar-dasar decorator TypeScript. Ingat, seperti belajar untuk membuat kue kering sempurna, menguasai decorators memerlukan latihan. Jangan khawatir untuk mencoba dan membuat kesalahan - itu adalah bagaimana kita belajar dan tumbuh sebagai pemrogram. Selamat coding!

Credits: Image by storyset