Kari ialah teknik pengaturcaraan berfungsi yang mengubah fungsi dengan berbilang argumen kepada urutan fungsi, masing-masing mengambil satu hujah. Pendekatan ini amat berguna untuk mencipta lebih banyak fungsi modular dan boleh digunakan semula, membenarkan penggunaan separa hujah. Dalam TypeScript, melaksanakan fungsi kari yang cekap memerlukan pengurusan jenis yang teliti, terutamanya apabila berurusan dengan bilangan argumen yang berubah-ubah.
Dalam artikel ini, kami akan meneroka dua pelaksanaan berbeza bagi fungsi kari dalam TypeScript. Yang pertama menggunakan antara muka dengan jenis statik, manakala yang kedua menggunakan pendekatan yang lebih fleksibel menggunakan antara muka tunggal dengan jenis variadic. Kami akan menganalisis perbezaan antara kedua-dua pelaksanaan ini dan membincangkan kelebihan pendekatan yang lebih dioptimumkan.
Dalam pelaksanaan pertama, saya menentukan satu siri antara muka untuk mengendalikan fungsi kari dengan bilangan hujah yang berbeza-beza. Setiap antara muka sepadan dengan fungsi dengan bilangan argumen tertentu:
interface CurryFunction1{ (arg1: T1): R; } interface CurryFunction2 { (arg1: T1): CurryFunction1 ; } interface CurryFunction3 { (arg1: T1): CurryFunction2 ; } interface CurryFunction4 { (arg1: T1): CurryFunction3 ; } interface CurryFunction5 { (arg1: T1): CurryFunction4 ; } interface CurryFunction6 { (arg1: T1): CurryFunction5 ; }
Fungsi kari ditakrifkan untuk menggunakan antara muka ini untuk kari fungsi dengan sehingga enam argumen:
function curry(fn: (arg1: T1, arg2: T2) => R): CurryFunction2 ; function curry (fn: (arg1: T1, arg2: T2, arg3: T3) => R): CurryFunction3 ; function curry (fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4) => R): CurryFunction4 ; function curry (fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5) => R): CurryFunction5 ; function curry (fn: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6) => R): CurryFunction6 ; function curry(fn: Function) { return function curried(...args: any[]) { if (args.length >= fn.length) { return fn(...args); } else { return (...args2: any[]) => curried(...args, ...args2); } }; }
Fungsi ini kemudiannya diuji untuk memastikan ia berfungsi dengan betul dengan bilangan hujah yang berbeza:
function testCurry() { const add = (a: number, b: number) => a + b; const curriedAdd = curry(add); assert(curriedAdd(1)(2) === 3, 'Test curry function with 2 arguments'); const add3Args = (a: number, b: number, c: number) => a + b + c; const curriedAdd3Args = curry(add3Args); assert(curriedAdd3Args(1)(2)(3) === 6, 'Test curry function with 3 arguments'); }
Walaupun pelaksanaan ini jelas dan tipikal bagi TypeScript, ia mempunyai beberapa batasan. Terutamanya, ia memerlukan takrifan berbilang antara muka untuk setiap bilangan argumen yang mungkin, menjadikan kod itu berlebihan dan lebih sukar untuk dikekalkan. Selain itu, pengendalian lebih daripada enam hujah memerlukan penambahan lebih banyak antara muka, meningkatkan kerumitan.
Untuk mengoptimumkan fungsi kari, saya menggunakan pendekatan yang lebih dinamik menggunakan antara muka generik tunggal dengan jenis variadic. Pendekatan ini membolehkan mengendalikan bilangan hujah yang sewenang-wenangnya tanpa perlu menentukan antara muka yang berasingan untuk setiap kes.
Dalam versi yang dioptimumkan ini, fungsi kari dilaksanakan menggunakan antara muka generik tunggal yang memanfaatkan jenis variadik TypeScript untuk mengendalikan bilangan hujah yang sewenang-wenangnya:
type CurryFunction= T extends [infer A, ...infer Rest] ? (arg: A) => CurryFunction : R; function curry (fn: (...args: T) => R): CurryFunction { return function curried(...args: unknown[]): unknown { if (args.length >= fn.length) { return fn(...args as T); } else { return (...args2: unknown[]) => curried(...([...args, ...args2] as unknown[])); } } as CurryFunction ; }
Kerumitan Dikurangkan: Dengan menggunakan antara muka generik tunggal CurryFunction, pelaksanaan ini menghapuskan keperluan untuk mencipta berbilang antara muka untuk setiap bilangan argumen yang mungkin. Ini menjadikan kod lebih ringkas dan lebih mudah diselenggara.
Peningkatan Penaipan
Menguji Fungsi Kari Dioptimumkan
function testCurry() { const add = (a: number, b: number) => a + b; const curriedAdd = curry(add); assert(curriedAdd(1)(2) === 3, 'Test curry function with 2 arguments'); const add3Args = (a: number, b: number, c: number) => a + b + c; const curriedAdd3Args = curry(add3Args); assert(curriedAdd3Args(1)(2)(3) === 6, 'Test curry function with 3 arguments'); const add4Args = (a: number, b: number, c: number, d: number) => a + b + c + d; const curriedAdd4Args = curry(add4Args); assert(curriedAdd4Args(1)(2)(3)(4) === 10, 'Test curry function with 4 arguments'); }
Peralihan daripada struktur dengan berbilang antara muka kepada antara muka generik tunggal ialah contoh yang bagus tentang cara memahami dan menggunakan konsep TypeScript lanjutan boleh membawa kepada penyelesaian yang lebih elegan dan cekap.
Atas ialah kandungan terperinci Mengoptimumkan Fungsi Kari TypeScript: Daripada Jenis Statik kepada Jenis Variadik. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!