View on GitHub: https://tsch.js.org/8767
Given an array of strings, do Permutation & Combination.
It's also useful for the prop types like video controlsList
// expected to be `"foo" | "bar" | "baz" | "foo bar" | "foo bar baz" | "foo baz" | "foo baz bar" | "bar foo" | "bar foo baz" | "bar baz" | "bar baz foo" | "baz foo" | "baz foo bar" | "baz bar" | "baz bar foo"`
type Keys = Combination<["foo", "bar", "baz"]>;
접근 방식
코드
type MakeCombination<A extends string, B extends string> =
| A
| B
| `${A} ${B}`
| `${B} ${A}`;
type UnionCombination<A extends string, B extends string = A> = A extends B
? MakeCombination<A, UnionCombination<Exclude<B, A>>>
: never;
type Combination<T extends string[]> = UnionCombination<T[number]>;
코드 설명
MakeCombination
: 두 문자열을 받아, 순서를 바꾸어 조합하여 반환UnionCombination
: 문자열 유니온을 순회하며, 각 요소와 나머지 요소를 MakeCombination
함수에 전달하여 조합Combination
: 문자열 배열을 받아, UnionCombination
에 유니온으로 변환하여 넣어줌View on GitHub: https://tsch.js.org/8987
A subsequence is a sequence that can be derived from an array by deleting some or no elements without changing the order of the remaining elements.
예시
type A = Subsequence<[1, 2]>; // [] | [1] | [2] | [1, 2]
접근 방식
코드
type Combination<A extends string, B extends string> = [A] | [B] | [A, B];
type UnionCombination<A extends string, B extends string = A> = A extends B
? Combination<A, UnionCombination<Exclude<B, A>>>
: never;
type Subsequence<T extends any[]> = UnionCombination<T[number]>;
실패 이유
접근 방식
코드
type Subsequence<T extends any[]> = T extends [infer First, ...infer Rest]
? Subsequence<Rest> | [First, ...Subsequence<Rest>]
: [];
코드 설명
First
가 없을 경우(빈 배열일 경우) 빈 배열 리턴View on GitHub: https://tsch.js.org/9142
Implement type CheckRepeatedChars<S>
which will return whether type S
contains duplicated chars?
예시
type CheckRepeatedChars<'abc'> // false
type CheckRepeatedChars<'aba'> // true
접근 방식
코드
type CheckRepeatedChars<
T extends string,
Dup = ""
> = T extends `${infer First}${infer Rest}`
? First extends Dup
? true
: CheckRepeatedChars<Rest, Dup | First>
: false;
코드 설명
Dup
은 중복 관리하는 유니온Dup
에 해당 문자가 있는지 확인(extends
)Dup
에 해당 문자 추가해 재귀View on GitHub: https://tsch.js.org/9286
Given a string s, find the first non-repeating character in it and return its index. If it does not exist, return -1. (Inspired by leetcode 387)
접근 방식
index
를 반환하고, 아닐 경우 -1 반환코드
// C가 T에서 유니크한지 확인
type IsUnique<
T extends string,
C extends string,
Count extends unknown[] = []
> = T extends `${infer First}${infer Rest}`
? C extends First
? IsUnique<Rest, C, [...Count, unknown]>
: IsUnique<Rest, C, Count>
: Count["length"] extends 1
? true
: false;
// 각 글자마다 전체 중복검사하면서, 중복 아니면 인덱스 반환
type FirstUniqueCharIndex<
T extends string,
Original extends string = T,
IndexArr extends unknown[] = []
> = T extends `${infer First}${infer Rest}`
? IsUnique<Original, First> extends true
? IndexArr["length"]
: FirstUniqueCharIndex<Rest, Original, [...IndexArr, unknown]>
: -1;
코드 설명
IsUnique
타입은 문자열에서 유니크한 문자가 있는지 확인C
는 확인할 문자(Character), T
를 순회하며 C
가 T
의 요소인지 infer
를 활용해 확인Count
는 중복 횟수를 카운트하는 배열. 중복되면 배열에 요소를 추가하고, 중복되지 않으면 배열에 요소를 추가하지 않음 (중복 횟수가 1인지 확인)FirstUniqueCharIndex
타입은 문자열을 순회하며, IsUnique
타입을 활용해 유니크한 문자인지 확인IndexArr
배열의 길이를 반환, 아닐 경우 재귀 호출View on GitHub: https://tsch.js.org/9616
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
접근 방식
first
, :
, param
, /
, rest
로 나누어 파싱코드
type ParseUrlParams<T> = T extends `${infer _}:${infer Param}/:${infer Rest}`
? Param | ParseUrlParams<Rest>
: T extends `${infer _}:${infer Param}`
? Param extends `${infer First}/`
? First
: Param
: never;
코드 설명
first
, :
, param
, /
, rest
로 나누어 파싱:
, /
, /:
각 조건의 맞게 확인실패 이유
접근 방식
/
단위로 나누고, 그다음에 :
가 붙어있는지 확인코드
type ParseUrlParams<T> = T extends `${infer Start}/${infer Rest}`
? ParseUrlParams<Start> | ParseUrlParams<Rest>
: T extends `:${infer Param}`
? Param
: never;
코드 설명
/
단위로 나누고, 그다음에 :
가 붙어있는지 확인:
가 붙어있으면, 그 문자를 유니온 타입으로 반환:
가 붙어있지 않으면, never
반환View on GitHub: https://tsch.js.org/9896
Get the middle element of the array by implementing a GetMiddleElement
method, represented by an array
If the length of the array is odd, return the middle element
If the length of the array is even, return the middle two elements
예시
type simple1 = GetMiddleElement<[1, 2, 3, 4, 5]>, // expected to be [3]
type simple2 = GetMiddleElement<[1, 2, 3, 4, 5, 6]> // expected to be [3, 4]
접근 방식
코드
type GetMiddleElement<T extends any[]> = T extends [
infer _F,
...infer R,
infer _L
]
? GetMiddleElement<R>
: T;
코드 설명
infer _F
와 infer _L
은 양쪽 요소를 제거하기 위해 사용...infer R
은 중간 요소를 찾기 위해 사용실패 이유
접근 방식
코드
type GetMiddleElement<T extends any[]> = T extends [infer F, infer L]
? [F, L]
: T extends [infer _F, ...infer R, infer _L]
? GetMiddleElement<R>
: T;
코드 설명
infer F, infer L
) 얼리 리턴