본문 바로가기

FE/type-challenge

10969. Integer

728x90

문제

Please complete type Integer<T>, type T inherits from number, if T is an integer return it, otherwise return never.

cases

let x = 1
let y = 1 as const

type cases1 = [
  Expect<Equal<Integer<1>, 1>>,
  Expect<Equal<Integer<1.1>, never>>,
  Expect<Equal<Integer<1.0>, 1>>,
  Expect<Equal<Integer<1.000000000>, 1>>,
  Expect<Equal<Integer<0.5>, never>>,
  Expect<Equal<Integer<28.00>, 28>>,
  Expect<Equal<Integer<28.101>, never>>,
  Expect<Equal<Integer<typeof x>, never>>,
  Expect<Equal<Integer<typeof y>, 1>>,
]

문제 링크

정답

type Integer<T extends number, U extends string = `${T}`, Checking extends boolean = false, Result extends string = ''> =
    [1, 2] extends [T, T]
      ? never
      : U extends `${infer U1}${infer Rest}`
        ? Checking extends true
          ? U1 extends '.'
            ? never
            : U1 extends '0' ? Integer<T, Rest, true> : never
          : U1 extends '.'
            ? Integer<T, Rest, true>
            : Integer<T, Rest, false, `${Result}${U1}`>
        : Result extends `${infer K extends number}` ? K : never

풀이

조건

  1. 입력 T 의 소수점을 확인해서
    1. 소수점이 모두 0인 경우 정수값을 반환한다.
    1. 모두 0이 아닌 경우 never를 반환한다.
  1. Tnumberextends 해야한다.

해설

우선 소수점까지 확인하는 로직을 작성한다.

type Integer<T extends number, U extends string = `${T}`, Checking extends boolean = false, Result extends string = ''> =
  U extends `${infer U1}${infer Rest}`
    ? U1 extends '.'
        ? Integer<T, Rest, true>
        : Integer<T, Rest, false, `${Result}${U1}`>
		: never

위 코드에서 T 를 string으로 가지고 있기 위한 U, 소수점 돌입 여부를 확인하는 Checking, 결과값 Result가 추가되었다.

소수점 이전과 이후의 로직이 달라져야 하므로, 우선 소수점 이전까지의 로직을 구현한다.

type Integer<T extends number, U extends string = `${T}`, Checking extends boolean = false, Result extends string = ''> =
  U extends `${infer U1}${infer Rest}`
    ? Checking extends true
      ? // 소수점 이후의 로직
      : U1 extends '.'
        ? Integer<T, Rest, true>
        : Integer<T, Rest, false, `${Result}${U1}`>
    : Result extends `${infer K extends number}` ? K : never

위 코드에서 결과값 Result를 반환할 때, number로 변환하여 반환하는 로직을 추가했다.

소수점 이후의 로직을 구현한다.

type Integer<T extends number, U extends string = `${T}`, Checking extends boolean = false, Result extends string = ''> =
  U extends `${infer U1}${infer Rest}`
    ? Checking extends true
      ? U1 extends '.'
        ? never
        : U1 extends '0' ? Integer<T, Rest, true> : never
      : U1 extends '.'
        ? Integer<T, Rest, true>
        : Integer<T, Rest, false, `${Result}${U1}`>
    : Result extends `${infer K extends number}` ? K : never

대부분의 TC를 통과하지만, 예제에서 typeof x를 통과하지 못한다.

1이라는 타입과 number라는 타입의 차이를 이용해서 다음과 같이 확인하는 로직을 추가한다.

type Integer<T extends number, U extends string = `${T}`, Checking extends boolean = false, Result extends string = ''> =
    [1, 2] extends [T, T]
      ? never
      : U extends `${infer U1}${infer Rest}`
        ? Checking extends true
          ? U1 extends '.'
            ? never
            : U1 extends '0' ? Integer<T, Rest, true> : never
          : U1 extends '.'
            ? Integer<T, Rest, true>
            : Integer<T, Rest, false, `${Result}${U1}`>
        : Result extends `${infer K extends number}` ? K : never

오류나 수정사항이 있다면, 댓글 부탁드립니다.

728x90

'FE > type-challenge' 카테고리의 다른 글

16259. ToPrimitive  (0) 2023.09.22
9898. FindEles  (0) 2023.09.19
9896. GetMiddleElement  (0) 2023.09.12
9616. ParseUrlParams  (0) 2023.09.11
9286. FirstUniqueCharIndex  (0) 2023.09.07