커링은 여러 인수가 있는 함수를 각각 단일 인수를 사용하는 일련의 함수로 변환하는 함수형 프로그래밍 기술입니다. 이 접근 방식은 특히 모듈식이며 재사용 가능한 함수를 생성하여 인수를 부분적으로 적용할 수 있도록 하는 데 유용합니다. TypeScript에서 효율적인 카레 함수를 구현하려면 특히 가변 개수의 인수를 처리할 때 신중한 유형 관리가 필요합니다.
이 기사에서는 TypeScript에서 카레 함수를 구현하는 두 가지 방법을 살펴보겠습니다. 첫 번째는 정적 유형의 인터페이스를 사용하는 반면, 두 번째는 가변 유형의 단일 인터페이스를 사용하는 보다 유연한 접근 방식을 채택합니다. 이 두 가지 구현 간의 차이점을 분석하고 보다 최적화된 접근 방식의 장점에 대해 논의하겠습니다.
첫 번째 구현에서는 다양한 수의 인수를 사용하여 카레 함수를 처리하기 위한 일련의 인터페이스를 정의했습니다. 각 인터페이스는 특정 개수의 인수를 갖는 함수에 해당합니다:
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 ; }
curry 함수는 다음 인터페이스를 사용하여 최대 6개의 인수가 있는 함수를 curry하도록 정의됩니다.
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); } }; }
그런 다음 이 함수는 다양한 수의 인수와 함께 올바르게 작동하는지 테스트됩니다.
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'); }
이 구현은 TypeScript의 명확하고 일반적인 구현이지만 몇 가지 제한 사항이 있습니다. 특히 가능한 각 인수 수에 대해 여러 인터페이스를 정의해야 하므로 코드가 중복되고 유지 관리가 더 어려워집니다. 또한 6개 이상의 인수를 처리하려면 더 많은 인터페이스를 추가해야 하므로 복잡성이 증가합니다.
카레 기능을 최적화하기 위해 가변 유형의 단일 일반 인터페이스를 사용하는 보다 동적인 접근 방식을 채택했습니다. 이 접근 방식을 사용하면 각 사례에 대해 별도의 인터페이스를 정의할 필요 없이 임의 개수의 인수를 처리할 수 있습니다.
이 최적화된 버전에서 curry 함수는 TypeScript의 가변 유형을 활용하여 임의 개수의 인수를 처리하는 단일 일반 인터페이스를 사용하여 구현됩니다.
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 ; }
복잡성 감소: 단일 일반 인터페이스 CurryFunction을 사용함으로써 이 구현에서는 가능한 모든 인수 수에 대해 여러 인터페이스를 만들 필요가 없습니다. 이렇게 하면 코드가 더욱 간결해지고 유지 관리가 쉬워집니다.
임의의 인수 지원: 가변 유형을 활용하면 이 함수가 구현을 수정하지 않고도 인수 개수에 관계없이 함수를 커리할 수 있습니다. 따라서 이 기능은 다양한 시나리오에 더욱 유연하고 적응할 수 있습니다.
향상된 타이핑: 동적 타이핑을 통해 TypeScript는 인수 유형을 정확하게 추론하여 개발 중에 더 강력한 유형 검사를 제공하고 오류 위험을 줄이고 코드 완성을 향상시킵니다.
이 버전의 카레 기능은 올바르게 작동하는지 테스트되었습니다.
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'); }
TypeScript의 카레 함수 최적화는 가변 유형을 채택하여 정적 인터페이스 기반 접근 방식을 어떻게 개선할 수 있는지 보여줍니다. 새로운 구현은 코드 복잡성을 줄일 뿐만 아니라 더 큰 유연성과 더 강력한 유형 검사를 제공합니다. 이 예에서는 TypeScript의 기능을 완전히 활용하여 더욱 깔끔하고, 모듈화되고, 유지 관리 가능한 코드를 만드는 것이 얼마나 중요한지 강조합니다.
여러 인터페이스가 있는 구조에서 단일 일반 인터페이스로 전환하는 것은 고급 TypeScript 개념을 이해하고 적용하여 더욱 우아하고 효율적인 솔루션으로 이어질 수 있는 방법을 보여주는 좋은 예입니다.
부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.
Copyright© 2022 湘ICP备2022001581号-3