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!
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:
- Menambah metadata ke kode Anda
- Mengubah perilaku kelas dan metode
- Mengimplementasikan aspek dari Aspect-Oriented Programming
- 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