inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

[리뉴얼] 타입스크립트 올인원 : Part1. 기본 문법편

완전 복잡한 타입 분석하기(flat 편)

혹시 저처럼 flat 분석 헤매실 분들을 위해 남깁니다.

394

바스니카
1

틀린 부분 있으면 댓글로 알려주세요!

시작 전

먼저 배열에 대해 알아볼게요.

자바스크립트에서 배열의 타입은 object입니다.

그럼 어떻게 구성되어 있는 걸까요?

const a = [1, 2, 3] 으로 알아볼게요.

{ 0: 1, 1: 2, 2: 3, length: 3 } 꼴의 특수한 객체라는 사실을 알 수 있어요. 특수하다고 말한 이유는 대괄호 표기법을 사용할 때 2가지 방법이 가능하기 때문이에요.

참고로 key들의 타입은 number입니다. 타입스크립트를 통해 알 수 있어요.

interface myArray<T> {
  [n: number]: T;
}

const arr: myArray<number> = [1, 2, 3];
interface myArray<T> {
  [n: string]: T;
}

const arr: myArray<number> = [1, 2, 3]; // 에러

 

지금까지 배열은 key 타입이 number로 이루어진 특수한 객체라는 사실을 배웠어요.

interface ReadonlyArray<T>{
  ...
  readonly [n: number]: T;
  ...
}

이제 우린 ReadonlyArray<T>가 배열을 의미한다는 걸 알죠.

 

시작

제가 이해를 못했던 부분은 재귀를 할 때마다 배열이 한 차원씩 내려간다는 거였어요. 그래서 이 부분을 중점적으로 설명할게요.

예시는 [1, 2, [3, 4], [[5, 6]]].flat(2) 로 할게요.

1.

flat<A, D extends number = 1>(
        this: A,
        depth?: D
    ): FlatArray<A, D>[]

A는 (number | number[] | number[][])[]이고,

D는 2입니다.

 

2.

type FlatArray<Arr, Depth extends number> = {
    "done": Arr,
    "recur": Arr extends ReadonlyArray<infer InnerArr>
        ? FlatArray<InnerArr, [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20][Depth]>
        : Arr
}[Depth extends -1 ? "done" : "recur"];

Depth가 2라서 "recur"로 갑니다.

Arr은 (number | number[] | number[][])[]겠죠?

Arr을 다르게 표현해 볼게요.

{ 0: number, 1: number[], 2: number[][], length: 3 }

extends가 있으니 ReadonlyArray를 만족하는 Arr을 찾아야 해요.

그리고 InnerArr은 ReadonlyArray<T>에서 T에 해당하겠죠? 그리고 T는 number | number[] | number[][]에요.

따라서, InnerArr은 number | number[] | number[][]죠.

 

3.

재귀를 하네요.

Arr은 이제 number | number[] | number[][]고,

Depth는 1이에요. "recur"로 갑니다.

마찬가지로 ReadonlyArray와 비교해야죠.

number는 배열이 아니므로 제외됩니다.

number[]는 { 0: number, length: 1}이고,

number[][]는 {0: number[], length: 1}입니다.

그래서 InnerArr은 number | number[]죠.

 

4.

재귀를 합니다.

Arr은 이제 number | number[]고,

Depth는 0이에요. "recur'로 갑니다.

3과 같이 수행하면 InnerArr은 number가 됩니다.

 

5.

재귀를 합니다.

Depth가 -1이네요? "done"으로 갑니다.

Arr가 number니까 number가 리턴됩니다.

 

6.

flat<A, D extends number = 1>(
        this: A,
        depth?: D
    ): FlatArray<A, D>[]

FlatArray<A, D>가 number라는 걸 알았어요,

그래서 flat은 number[]를 반환하는 거죠.

이러한 과정을 거치기 때문에,

[1, 2, [3, 4], [[5, 6]]].flat(2) 의 타입이 number[]가 됩니다.

 

도움이 되셨으면 좋겠네요 :)

답변 0