개발

[Typescript] 짝수, 홀수 타입 만들기

dohye1 2022. 11. 18. 10:32
반응형

타입스크립트로 짝수 또는 홀수에 대한 타입을 만들어보는 방법을 찾아보다가 기록하면 좋을것같아서 포스팅해봄

 

일단 처음엔 어떻게 접근해야할지 감이 잘 안와서 구글에 찾아봄

https://dev.to/tylim88/typescript-odd-number-type-1fj

 

Typescript Odd Number Type

Most people: No, you cannot create an odd number type with Typescript Meanwhile me: type...

dev.to

그러다가 위 블로그를 보게되었당!

Acid Coder선생님 감사합니다ㅜㅠㅜ흐릏그ㅡ

홀수 타입

type OddNumber<
    X extends number,
    Y extends unknown[] = [1],
    Z extends number = never
> = Y['length'] extends X
    ? Z | Y['length']
    : OddNumber<X, [1, 1, ...Y], Z | Y['length']>

type a = OddNumber<1> // 1 
type b = OddNumber<3> // 1 | 3
type c = OddNumber<5> // 1 | 3 | 5
type d = OddNumber<7> // 1 | 3 | 5 | 7

OddNumber를 호출하고, 넘버타입의 타입변수를 넘겨주면된다!

그럼 내가 넘겨준 타입변수(X) 이하의 값들로 이루어진 홀수값 유니온 타입이 만들어진다.

짝수 타입

type EvenNumber<
    X extends number,
    Y extends unknown[] = [1, 1],
    Z extends number = never
> = Y['length'] extends X
    ? Z | Y['length']
    : EvenNumber<X, [1, 1, ...Y], Z | Y['length']>

type e = EvenNumber<2> // 2
type f = EvenNumber<4> // 2 | 4
type g = EvenNumber<6> // 2 | 4 | 6


const test : g = 7; // error

EvenNumber를 호출하고, 넘버타입의 타입변수를 넘겨주면된다!

그럼 내가 넘겨준 타입변수(X) 이하의 값들로 이루어진 짝수값 유니온 타입이 만들어진다.

 

뜯어보기

미리 알고있어야 할것

1. number extends number

이 문법은 처음 봤는데, 숫자를 extend하게되면

숫자끼리 같은 값인지 확인한다.

 

2. Y['length']

배열의 길이를 확인할 때 arr.length로 많이 접근했는데,

여기서는 Y['length']이렇게 접근한다!

 

Y.length로 접근하게되면 아래와 같은 에러가 뜬다.

 

일단 배열은 객체이다 > 배열의 프로퍼티 중 length가 있다 > 그래서 Y['length'] 이런식으로 접근한건가...?

이 부분에 대해서는 내 논리회로가 맞는진 잘 모르겠음ㅜ

 

그럼 이제 타입을 자세히 이해해보자

나는 타입선언한것 자체로는 이해하기가 힘들어서 실제 값을 넣어서 흐름을 파악해보고자 했다!

 

짝수 타입의 유니온을 반환하는 EvenNumber 예시

위 이미지로 이해하기 쉬울거라고 생각해서 설명을 더 안해도될것같음!

 

처음에 좀 헷갈렸던 부분이 

Z | Y['length']
 
이렇게 된 부분에서, 나는 Z값이 있으면 Z를 반환하고, 없으면 Y['length']를 반환해라 라고 인줄알았는데,
유니온 타입을 의미하는거였당.
 
js랑 ts를 섞어서 생각해서 그런강....ㅋㅋㅋㅋ

 

변형

1. n의 배수를 뽑아내고 싶을때

// 3의 배수를 뽑아낸다고 가정

type EvenNumber<
    X extends number,
    Y extends unknown[] = [1, 1, 1], // n(===3)개 만큼 1을 적어준다.
    Z extends number = never
> = Y['length'] extends X
    ? Z | Y['length']
    : EvenNumber<X, [1, 1, 1, ...Y], Z | Y['length']> // n(===3)개 만큼 1을 적어준다. [1, 1, 1, ...Y]

3의 배수를 반환하고, 최댓값이 6이라고 한다면 아래의 과정을 거쳐 결과가 도출된다.

 



아 그리고 주의사항이 있는데 위에 첨부한 블로그에 아래문구가 있었당

with some limitations, the input must an odd number, and cannot exceed 1999 (maximum depth of typescript recursion is only 1000)

몰랐던 내용인데 주의해서 쓰자!

 

간단하게 테스트하고싶다면 typescript playground에 가서 확인해보십쇼소소송!

https://www.typescriptlang.org/play