>  기사  >  웹 프론트엔드  >  TypeScript의 재귀 유형 익히기: 깊이 제한을 적절하게 처리하기

TypeScript의 재귀 유형 익히기: 깊이 제한을 적절하게 처리하기

Susan Sarandon
Susan Sarandon원래의
2024-11-23 04:43:19133검색

Mastering Recursive Types in TypeScript: Handling Depth Limitations Gracefully

소개

TypeScript에서 깊게 중첩된 데이터 구조로 작업할 때 이러한 구조를 변환하는 유틸리티 유형을 만드는 것은 일반적인 작업입니다. 그러나 재귀 유형은 강력하기는 하지만 나름의 과제도 가지고 있습니다.

그러한 과제 중 하나는 유형 계산이 TypeScript의 기능을 초과하지 않도록 재귀 깊이를 효과적으로 제어하는 ​​것입니다. 이 기사에서는 유형 수준 숫자를 증가 및 감소시키는 일반적인 접근 방식을 살펴보고, 그 한계를 식별하고, 적절한 Increment 및 Decrement 유형을 사용하여 재귀 깊이를 관리하기 위한 강력한 솔루션을 제시합니다.

? 기본 유형 수준 숫자 연산의 문제

제한 사항을 더 잘 이해하기 위해 유형 수준에서 숫자를 늘리거나 줄일 때 자주 사용되는 순진한 접근 방식을 살펴보겠습니다.

type Prev = [never, 0, 1, 2, 3, 4];
type Next = [1, 2, 3, 4, 5, 6];

type MinusOne = Prev[5]; // ? 4
type PlusOne = Next[5];  // ? 6

? 문제 시나리오: 깊게 중첩된 선택적 속성

깊이 중첩된 개체 유형이 있고 모든 개체 유형을 만들고 싶다고 가정합니다.
지정된 수준까지 선택적인 속성:

type DeepObject = {
  a: number;
  b: {
    c: string;
    d: {
      e: boolean;
      f: {
        g: string;
        h: {
          i: number;
          j: {
            k: string;
          };
        };
      };
    };
  };
};

순진하고 하드코딩된 접근 방식을 사용하면 속성이 선택 사항이 되는 깊이를 관리하는 방법은 다음과 같습니다.

type Prev = [never, 0, 1, 2, 3, 4];

type DeepOptional<
  T,
  Limit extends number = 1
> = Limit extends never
  ? never
  : {
      [K in keyof T]?: T[K] extends object
        ? DeepOptional<T[K], Prev[Limit]>
        : T[K];
    };

설명:

  • DeepOptional은 속성을 Limit까지 선택적으로 만듭니다.
  • Limit은 정적 튜플에서 감소된 값을 가져오는 데 사용됩니다.

사용 예:

type NewDeepObject = DeepOptional<DeepObject, 3>;

// Result:
// {
//   a?: number;
//   b?: {
//     c?: string;
//     d?: {
//       e?: boolean;
//       f?: {
//         g: string;
//         h: {
//           i: number;
//           j: {
//             k: string;
//           };
//         };
//       };
//     };
//   };
// };

type NewDeepObject = DeepOptional<DeepObject, 1>;

// Result:
// {
//   a?: number;
//   b?: {
//     c: string;
//     d: {
//       e: boolean;
//       f: {
//         g: string;
//         h: {
//           i: number;
//           j: {
//             k: string;
//           };
//         };
//       };
//     };
//   };
// };

✋ 이 접근 방식의 문제

  • 제한된 범위: 이 접근 방식은 사전 정의된 Prev 및 Next 배열만큼만 유연합니다. 이러한 배열의 길이를 초과하여 숫자를 늘리거나 줄여야 하는 경우 수동으로 확장해야 하며 이는 번거롭고 오류가 발생하기 쉽습니다.
  • 확장성: 요구 사항이 발전함에 따라 이러한 어레이 관리가 점점 더 복잡해지며 대규모 유형 작업에는 이 접근 방식이 실용적이지 않습니다.

? 더욱 강력한 솔루션: 튜플 기반 증가 및 감소 유형

미리 정의된 배열의 한계를 극복하기 위해 튜플 조작을 사용하여 동적으로 확장되는 유형이 안전한 증가 및 감소 연산을 생성할 수 있습니다.

?️ 주요 빌딩 블록

  • 길이 유틸리티: 튜플의 길이를 가져오는 유형:
type Prev = [never, 0, 1, 2, 3, 4];
type Next = [1, 2, 3, 4, 5, 6];

type MinusOne = Prev[5]; // ? 4
type PlusOne = Next[5];  // ? 6
  • TupleOf: N 요소의 튜플을 생성하는 유형:
type DeepObject = {
  a: number;
  b: {
    c: string;
    d: {
      e: boolean;
      f: {
        g: string;
        h: {
          i: number;
          j: {
            k: string;
          };
        };
      };
    };
  };
};
  • 팝 유틸리티: 튜플의 마지막 요소를 제거하는 유형:
type Prev = [never, 0, 1, 2, 3, 4];

type DeepOptional<
  T,
  Limit extends number = 1
> = Limit extends never
  ? never
  : {
      [K in keyof T]?: T[K] extends object
        ? DeepOptional<T[K], Prev[Limit]>
        : T[K];
    };
  • 증가 및 감소:
type NewDeepObject = DeepOptional<DeepObject, 3>;

// Result:
// {
//   a?: number;
//   b?: {
//     c?: string;
//     d?: {
//       e?: boolean;
//       f?: {
//         g: string;
//         h: {
//           i: number;
//           j: {
//             k: string;
//           };
//         };
//       };
//     };
//   };
// };

type NewDeepObject = DeepOptional<DeepObject, 1>;

// Result:
// {
//   a?: number;
//   b?: {
//     c: string;
//     d: {
//       e: boolean;
//       f: {
//         g: string;
//         h: {
//           i: number;
//           j: {
//             k: string;
//           };
//         };
//       };
//     };
//   };
// };

? 증가 및 감소 적용: 실제 예

이러한 유틸리티 유형을 보다 복잡한 실제 문제에 어떻게 적용할 수 있는지 살펴보겠습니다. 즉, 객체의 속성을 특정 깊이까지 선택적으로 만드는 것입니다.

문제 시나리오: 깊게 중첩된 선택적 속성

깊이 중첩된 개체 유형이 있고 모든 개체 유형을 만들고 싶다고 가정합니다.
지정된 수준까지 선택적인 속성:

type Length<T extends any[]> = (T extends { length: number } ? T["length"] : never) & number;

순진하고 하드코딩된 접근 방식을 사용하면 속성이 선택 사항이 되는 깊이를 관리하는 것이 복잡해집니다. 유형이 안전한 DeepOptional 유틸리티가 이 문제를 해결하는 방법은 다음과 같습니다.

DeepOptional 구현

type TupleOf<N extends number, T extends unknown[] = []> = Length<T> extends N
  ? T
  : TupleOf<N, [...T, unknown]>;

설명:

  • DeepOptional은 속성을 Limit까지 선택적으로 만듭니다.
  • 이 유형은 Limit과 일치할 때까지 CurrentLevel을 재귀적으로 증가시키고, 이 시점에서 반복을 멈추고 T를 반환합니다.
  • 증분 수동 배열 매핑 없이 유형이 안전한 재귀를 보장합니다.

사용 예:

type Pop<T extends any[]> = T extends [...infer U, unknown] ? U : never;

?️ 결론

medusajs에서는 복잡한 기술 문제를 극복할 수 있는 가장 효율적이고 혁신적인 솔루션을 찾기 위해 최선을 다하고 있습니다. 튜플 기반 증가 및 감소 유형을 활용하면 기본 유형 수준 작업의 한계를 넘어 확장 가능하고 유형이 안전한 유틸리티를 만들 수 있습니다. 이 방법은 재귀 깊이 관리를 단순화할 뿐만 아니라 TypeScript의 유형 검사 제한을 초과하지 않고 복잡한 유형 작업에 필요한 유연성을 유지하도록 보장합니다.

위 내용은 TypeScript의 재귀 유형 익히기: 깊이 제한을 적절하게 처리하기의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.