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
풀이
조건
- 입력
T
의 소수점을 확인해서- 소수점이 모두 0인 경우 정수값을 반환한다.
- 모두 0이 아닌 경우
never
를 반환한다.
T
는number
를extends
해야한다.
해설
우선 소수점까지 확인하는 로직을 작성한다.
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 |