FE/type-challenge
9616. ParseUrlParams
최토피
2023. 9. 11. 12:08
728x90
문제
You're required to implement a type-level parser to parse URL params string into an Union.
ParseUrlParams<':id'> // id
ParseUrlParams<'posts/:id'> // id
ParseUrlParams<'posts/:id/:user'> // id | user
cases
type cases = [
Expect<Equal<ParseUrlParams<''>, never>>,
Expect<Equal<ParseUrlParams<':id'>, 'id'>>,
Expect<Equal<ParseUrlParams<'posts/:id'>, 'id'>>,
Expect<Equal<ParseUrlParams<'posts/:id/'>, 'id'>>,
Expect<Equal<ParseUrlParams<'posts/:id/:user'>, 'id' | 'user'>>,
Expect<Equal<ParseUrlParams<'posts/:id/:user/like'>, 'id' | 'user'>>,
]
정답
type SplitSlash<T extends string> = T extends `${infer Rest1}/${infer Rest2}`
? [Rest1, ...SplitSlash<Rest2>]
: [T]
type ParseUrlParams<T extends string, Splited extends string[] = SplitSlash<T>> =
Splited extends [infer S1, ...infer Rest extends string[]]
? (S1 extends `:${infer Word}` ? Word : never) | ParseUrlParams<T, Rest>
: never
풀이
조건
:
뒤에 오는 파라미터를 파싱한다.
- 이외의 path는 포함하지 않는다.
해설
path는 /를 기준으로 나뉘므로, /로 slice하는 타입을 구현한다.
type SplitSlash<T extends string> = T extends `${infer Rest1}/${infer Rest2}`
? [Rest1, ...SplitSlash<Rest2>]
: [T]
분리된 string[]를 하나씩 검사한다. 파라미터는 앞에 : 기호가 오므로 이를 확인하여 해당하는 항목만 출력한다.
type SplitSlash<T extends string> = T extends `${infer Rest1}/${infer Rest2}`
? [Rest1, ...SplitSlash<Rest2>]
: [T]
type ParseUrlParams<T extends string, Splited extends string[] = SplitSlash<T>> =
Splited extends [infer S1, ...infer Rest extends string[]]
? (S1 extends `:${infer Word}` ? Word : never) | ParseUrlParams<T, Rest>
: never
오류나 개선사항이 있다면 댓글 부탁드립니다.
728x90