View on github: https://tsch.js.org/18220
Implement the type Filter<T, Predicate>
takes an Array T
, primitive type or union primitive type Predicate
and returns an Array include the elements of Predicate
.
Primitive Type
or Union Primitive Type
)에 해당하는 요소만 반환접근 방식
코드
type Filter<T extends any[], P> = T extends [infer First, ...infer Rest]
? First extends P
? [First, ...Filter<Rest, P>]
: [...Filter<Rest, P>]
: [];
코드 설명
View on github: https://tsch.js.org/21104
Given a pattern string P and a text string T, implement the type FindAll<T, P>
that returns an Array that contains all indices (0-indexed) from T where P matches.
T
와 패턴 문자열 P
를 받아, P
가 T
에 존재하는 모든 인덱스를 배열로 반환접근 방식
코드
type GetIndex<
T extends string,
LengthArr extends unknown[] = []
> = T extends `${infer _}${infer Rest}`
? GetIndex<Rest, [unknown, ...LengthArr]>
: LengthArr["length"];
type FindAll<
T extends string,
P extends string
> = T extends `${infer Left}${P}${infer Rest}`
? [GetIndex<Left>, ...FindAll<Rest, P>]
: [];
코드 설명
${infer Left}${P}${infer Rest}
를 활용해 P가 존재하는지 확인P
가 존재할 경우, Left
의 길이를 리턴하고, 이후 Rest
에 대해 재귀 처리P
가 존재하지 않을 경우, 빈 배열 반환실패 이유
rest
문자열만 재귀처리하니까, 두번째 요소에 대해서는 뒷쪽(rest
내)의 index를 구함rest
로 분리하게 되면, AAAA
, AA
를 통과를 못시킬듯접근 방식
T
의 한 글자씩 순회하면서, P
의 첫 글자와 같으면 비교index
리턴 배열에 추가코드
type FindAll<
T extends string,
P extends string,
IndexArr extends unknown[] = []
> = T extends `${infer TFirst}${infer TRest}`
? P extends `${TFirst}${infer PRest}`
? TRest extends `${PRest}${infer _}`
? [IndexArr["length"], ...FindAll<TRest, P, [...IndexArr, unknown]>]
: [...FindAll<TRest, P, [...IndexArr, unknown]>]
: [...FindAll<TRest, P, [...IndexArr, unknown]>]
: [];
코드 설명
${infer TFirst}${infer TRest}
를 활용해 T
의 한 글자씩 순회P
의 첫 글자와 같으면(${TFirst}${infer PRest}
), TRest
가 P
문자열을 포함하는지 확인index
를 리턴 배열에 추가View on github: https://tsch.js.org/21106
ModifierKeys
provided, the priority of the previous value is higher than the latter value; that is, cmd ctrl
is OK, but ctrl cmd
is not allowed.접근 방식
코드
type MakeCombination<A extends string, B extends string> = `${A} ${B}`;
type UnionCombination<A extends string, B extends string = A> = [A] extends [
never
]
? ""
: A extends B
? MakeCombination<A, UnionCombination<Exclude<B, A>>>
: never;
type Combs<T extends any[]> = UnionCombination<T[number]>;
실패 이유
코드
type Combs<T extends string[] = ModifierKeys> = T extends [
infer F extends string,
...infer R extends string[]
]
? `${F} ${R[number]}` | Combs<R>
: never;
코드 설명
F
와 나머지 R
의 요소들을 묶은 string 리턴R
를 순회하면서 계속 조합View on github: https://tsch.js.org/21220
Given a generic tuple type T extends unknown[]
, write a type which produces all permutations of T
as a union.
예시
PermutationsOfTuple<[1, number, unknown]>;
// Should return:
// | [1, number, unknown]
// | [1, unknown, number]
// | [number, 1, unknown]
// | [unknown, 1, number]
// | [number, unknown, 1]
// | [unknown, number ,1]
접근 방식
코드
type Permutation<T, K = T> = [T] extends [never]
? []
: K extends K
? [K, ...Permutation<Exclude<T, K>>]
: never;
type PermutationsOfTuple<T extends unknown[]> = Permutation<T[number]>;
실패 이유
코드
type PermutationsOfTuple<
T extends unknown[],
Prev extends unknown[] = []
> = T extends [infer First, ...infer Rest]
?
| [First, ...PermutationsOfTuple<[...Prev, ...Rest]>]
| (Rest extends [] ? never : PermutationsOfTuple<Rest, [...Prev, First]>)
: [];
코드 설명
T
를 순회하며, First
및 Rest
분리First
와 Prev
, Rest
를 조합Rest
가 빈 배열일 경우 never
반환Rest
와 ...Prev, First
를 재귀 호출View on github: https://tsch.js.org/25170
Implement the type ReplaceFirst<T, S, R>
which will replace the first occurrence of S
in a tuple T
with R
. If no such S
exists in T
, the result should be T
.
T
에서 첫 번째로 나타나는 S
를 R
로 대체T
에 S
가 없다면, 결과는 T
접근 방식
S
와 같은 요소를 찾아서 R
로 대체코드
type ReplaceFirst<
T extends readonly unknown[],
S,
R,
Result extends any[] = []
> = T extends [infer First, ...infer Rest]
? First extends S
? [...Result, R, ...Rest]
: ReplaceFirst<Rest, S, R, [...Result, First]>
: Result;
코드 설명
S
와 같은 요소를 찾음 (extends
로 비교, IsEqual
로 비교시 two
와 string
비교 안됨)R
로 대체View on github: https://tsch.js.org/25270
The transpose of a matrix is an operator which flips a matrix over its diagonal; that is, it switches the row and column indices of the matrix A by producing another matrix, often denoted by AT.
예시
type Matrix = Transpose<[[1]]>; // expected to be [[1]]
type Matrix1 = Transpose<[[1, 2], [3, 4]]>; // expected to be [[1, 3], [2, 4]]
type Matrix2 = Transpose<[[1, 2, 3], [4, 5, 6]]>; // expected to be [[1, 4], [2, 5], [3, 6]]
접근 방식
코드
type GetElementByIndex<
T extends any[],
Idx extends number,
Cnt extends any[] = []
> = T extends [infer First, ...infer Rest]
? Cnt["length"] extends Idx
? First
: GetElementByIndex<Rest, Idx, [...Cnt, unknown]>
: never;
type PickColumn<M extends any[][], Idx extends number> = {
[K in keyof M]: GetElementByIndex<M[K], Idx>;
};
type Transpose<M extends number[][]> = M extends [
infer FirstRow extends any[],
...any
]
? { [K in keyof FirstRow]: PickColumn<M, Extract<K, number>> }
: [];
코드 설명
GetElementByIndex
는 행렬의 요소를 인덱스로 조회하는 함수PickColumn
은 행렬의 열을 추출하는 함수Transpose
는 행렬의 전치 연산을 수행하는 함수실패 이유
never
로 리턴접근 방식
코드
type Transpose<M extends number[][], R = M["length"] extends 0 ? [] : M[0]> = {
[X in keyof R]: {
[Y in keyof M]: X extends keyof M[Y] ? M[Y][X] : never;
};
};
코드 설명
R
로 행렬의 첫 번째 행을 가져옴M[Y][X]
형식으로 값을 넣어줌