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

풀이

조건

  1. :뒤에 오는 파라미터를 파싱한다.
  1. 이외의 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