本篇重點 在上一篇教學中,我們介紹了 TypeScript 中的 Generics(泛型)、Type Guarding(型別守衛) 以及 ES6 Modules(模組系統),,接下來本我們繼續進一步探討 TypeScript 中的 Decorators(裝飾器) 、Namespaces(命名空間) 以及 Utility Types(實用型別) 。
Decorators(裝飾器) 裝飾器是 TypeScript 中的一種特殊語法,它允許我們在不修改原始程式碼的情況下,為類別、方法、屬性或參數添加額外的功能。
1. 類別裝飾器 類別裝飾器用於修改或擴展類別的行為,它是一個函式,接受類別的建構函式作為參數。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 function logClass (target : Function ) { console .log (`Class ${target.name} is created.` ); } @logClass class MyClass { constructor ( ) { console .log ("MyClass instance created." ); } } const instance = new MyClass ();
2. 方法裝飾器 方法裝飾器用於修改或擴展類別中的方法,它接受三個參數:類別的原型、方法名稱以及方法的屬性描述。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 function logMethod (target : any , key : string , descriptor : PropertyDescriptor ) { const originalMethod = descriptor.value ; descriptor.value = function (...args : any [] ) { console .log ( `Calling method ${key} with arguments: ${JSON .stringify(args)} ` ); const result = originalMethod.apply (this , args); console .log (`Method ${key} returned: ${result} ` ); return result; }; return descriptor; } class Calculator { @logMethod add (a : number , b : number ): number { return a + b; } } const calc = new Calculator ();calc.add (2 , 3 );
3. 屬性裝飾器 屬性裝飾器用於修改或擴展類別中的屬性,它接受兩個參數:類別的原型以及屬性的名稱。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 function logProperty (target : any , key : string ) { let value = target[key]; const getter = function ( ) { console .log (`Getting value of property ${key} : ${value} ` ); return value; }; const setter = function (newVal : any ) { console .log (`Setting value of property ${key} to: ${newVal} ` ); value = newVal; }; Object .defineProperty (target, key, { get : getter, set : setter, enumerable : true , configurable : true , }); } class User { @logProperty name : string ; constructor (name : string ) { this .name = name; } } const user = new User ("Alice" );user.name = "Bob" ; console .log (user.name );
Namespaces(命名空間) 命名空間是 TypeScript 中用於組織程式碼的一種方式,它可以幫助我們避免全域變數的污染,並將相關的程式碼組織在一起,命名空間類似於模組,但它們的語法和用途有所不同。
1. 基本命名空間 使用 namespace 關鍵字來定義一個命名空間,並使用 export 關鍵字來匯出命名空間中的內容。
1 2 3 4 5 6 7 8 9 10 namespace MyNamespace { export function greet (name : string ): string { return `Hello, ${name} !` ; } export const PI = 3.14 ; } console .log (MyNamespace .greet ("Alice" )); console .log (MyNamespace .PI );
2. 嵌套命名空間 命名空間可以嵌套使用,以進一步組織程式碼。
1 2 3 4 5 6 7 8 9 namespace OuterNamespace { export namespace InnerNamespace { export function greet (name : string ): string { return `Hello, ${name} !` ; } } } console .log (OuterNamespace .InnerNamespace .greet ("Bob" ));
3. 命名空間與模組的區別 雖然命名空間和模組都可以用來組織程式碼,但它們的使用場景有所不同:
命名空間 :適合用於小型專案或需要避免全域變數污染的場景。
模組 :適合用於大型專案或需要與其他工具(如 Webpack、Rollup)整合的場景。
Utility Types(實用型別) TypeScript 提供了一些內建的實用型別,這些型別可以幫助我們更靈活地處理型別轉換與操作。
1. Partial<T> Partial<T> 可以將型別 T 的所有屬性設為可選。
1 2 3 4 5 6 7 8 9 10 interface User { name : string ; age : number ; } type PartialUser = Partial <User >;const user : PartialUser = { name : "Alice" , };
2. Required<T> Required<T> 可以將型別 T 的所有屬性設為必填。
1 2 3 4 5 6 7 8 9 10 11 interface User { name ?: string ; age ?: number ; } type RequiredUser = Required <User >;const user : RequiredUser = { name : "Alice" , age : 25 , };
3. Readonly<T> Readonly<T> 可以將型別 T 的所有屬性設為唯讀。
1 2 3 4 5 6 7 8 9 10 11 12 13 interface User { name : string ; age : number ; } type ReadonlyUser = Readonly <User >;const user : ReadonlyUser = { name : "Alice" , age : 25 , }; user.name = "Bob" ;
4. Pick<T, K> Pick<T, K> 可以從型別 T 中挑選出指定的屬性 K。
1 2 3 4 5 6 7 8 9 10 11 12 interface User { name : string ; age : number ; email : string ; } type UserNameAndAge = Pick <User , "name" | "age" >;const user : UserNameAndAge = { name : "Alice" , age : 25 , };
5. Omit<T, K> Omit<T, K> 可以從型別 T 中排除指定的屬性 K。
1 2 3 4 5 6 7 8 9 10 11 12 interface User { name : string ; age : number ; email : string ; } type UserWithoutEmail = Omit <User , "email" >;const user : UserWithoutEmail = { name : "Alice" , age : 25 , };
結論 在本篇中,我們深入探討了 TypeScript 中的 Decorators(裝飾器) 、Namespaces(命名空間) 以及 Utility Types(實用型別) ,包括:
裝飾器的基本用法與應用場景。
命名空間的定義與使用。
實用型別的介紹與範例。
延伸閱讀