리액트로 정렬하거나 줄이려는 당신에게~
38584 단어 JavaScriptReactTypeScripttech
🪝 What's this?
한마디로'React로 복잡한 정렬과 선별의 사용자 정의 연결을 간단하게 기술할 수 있다'는 뜻이다.
조금 더 자세히 쓰면 다음과 같은 기능이 있습니다.
!
일반적으로 정렬과 선별 주위의 논리는 백엔드에만 쓰이고 백엔드에서 받아들이면 되지만 여러 가지 이유로 백엔드에서 선별하고 정렬하고자 하는 사람들에게 유용한 프로그램 라이브러리이다.
그럼에도 불구하고 배열 조작 자체는 기술적으로 특별히 어려운 일이 없기 때문에 앞으로 이 프로그램 라이브러리를 개발할 때 풀린 퍼즐을 쓰고 싶습니다.(결국 이 퍼즐은 사용되지 않아 공양도 겸하고 있다)
🧩 퍼즐 유형
문제.
String 플랫폼의 Union Type을 받아들여'or'로 그 임의의 요소를 연결하는 유형을 만들어 보세요.
type OR<T extends string> = ...
type Key = 'A' | 'B' | 'C'
type OrKey = OR<Key> // 'A' | 'B' | 'C' | 'AorB' | 'AorC' | 'BorA' | 'BorC' | 'CorA' | 'CorB' | 'AorBorC' | 'AorCorB' | 'BorAorC' | 'BorCorA' | 'CorAorB' | 'CorBorA'
!원래는
OR<"A"|"B"> = "A" | "B" | "AorB"
였으면 했는데 TS에서 실력을 구별할 수 없는 조합OR<"A"|"B"> = "A" | "B" | "AorB" | "BorA"
의 장르를 이뤘다.만약 유식한 사람이 있다면 평론에서 저에게 알려주세요.두 가지 해법을 준비했습니다.✌️
각자의 해법에 작은 문제가 설정되어 있으니 이 큰 문제를 조금씩 공략해 나가자👍
(추기)게다가 댓글에서 가장 우아한 해법을 얻어 해법 1의 마지막에 실었다
해법 1
질문 1: Union 요소의 전체 정렬
type Permutation<T> = ...
Permutation<"A"|"B"|"C"> // ["A", "B", "C"] | ["A", "C", "B"] | ["B", "A", "C"] | ["B", "C", "A"] | ["C", "A", "B"] | ["C", "B", "A"]
해설type Permutation<T extends string, U extends string = T> = [T] extends [never]
? []
: T extends T
? [T, ...Permutation<Exclude<U, T>>]
: never;
첫 번째도 가장 큰 귀신이네요(웃음)사실 Type-Challenge는 완전히 같다문제..
여기 대략적인 설명 (더 자세한 내용은 영어로 쓴 것을 읽어주세요여기.
절차로서 T는 Union의 토대 위에서 조건절
foo extends bar
부분에서 그것을 분배하고 한 요소만 배열의 최초에 고정시키고 진열의 나머지 부분은 귀속적으로 처리한다.우선 최초
[T] extends [never]
에서 T가 네버인지 여부를 검사한다.일부러 []로 둘러친 것은 조건절에 네버가 오면 문답이 소용이 없기 때문에 결과적으로 네버가 되기 때문이다.조건절 유니온의 분배에 대해 잘 모르는 사람여기 기사.은 이해하기 쉽다.아래
T extends T
에서 매개변수 유니온을 지정합니다.('A'|'B'|'C'가 이곳에 온 뒤 이 말 뒤의 T는'A'와'B'등 배정된 요소였다.)그리고 Permutation의 형 매개 변수의 두 번째 매개 변수에 U=T를 추가하는 것은 T를 분배한 후에도 분배 전의 Union을 사용해야 하기 때문이다.이 불가사의한 기법에 대한 상세한 설명은 전미증여기 기사.에 대한 상세한 해설이다.질문 2: Union 요소의 모든 요소의 배열
type ArbitraryPermutation<T> = ...
ArbitraryPermutation<"A"|"B"|"C"> // ["A"] | ["B"] | ["C"] | ["A", "B"] | ["A", "C"], ... , ["A", "B", "C"] | ["A", "C", "B"], ...
해설type ArbitraryPermutation<T extends string, U extends string = T> = [T] extends [never]
? never
: Permutation<T> | (T extends T ? ArbitraryPermutation<Exclude<U, T>> : never);
모든 Union을 Permutation 이라고 부르는 조건부 분담작은 문제 1에 사용된 노하우(never 판정, Union의 분배)를 알면 이해할 수 있을 거야!
질문 3: "or"로 그룹 내의 요소 조합
type JoinWith<T, U> = ...
JoinWith<["A", "B", "C"], "or"> // "AorBorC"
해설type JoinWith<T extends string[], U extends string> = T extends [infer Head, ...infer Rest]
? Rest['length'] extends 0
? Head
: Head extends string
? Rest extends string[]
? `${Head}${U}${JoinWith<Rest, U>}`
: ''
: never
: never;
절차로서 infer
분해 배열을 사용하고'or'로 시작한 요소와 남은 요소를 연결하여 남은 요소를 귀속적으로 처리한다.infer
는 조건절에만 사용되는 키워드로 ...
와 함께 사용하면 유형의 세계에서 배열형과 문자열 소양을 분해하고 명명하며 이후의 유형 처리에 사용할 수 있다.Rest['length'] extends 0 ? Head
의 부분은 이 유형 함수의 기초 부분에 해당한다.Rest가 비어 있을 때, 즉 T는 길이 1의 정렬을Head 요소에 할당하고 Rest가 비어 있을 때 그 내용을 반환합니다.
질문 4:1-3 유닛의 모든 요소 또는 결합
type OR<T> = ...
OR<"A"|"B"|"C"> // "A" | "B" | "C" | "BorC" | "CorB" | "AorBorC" | "AorCorB" | "AorC" | "CorA" | "BorAorC" | "BorCorA" | "AorB" | "BorA" | "CorAorB" | "CorBorA"
예제type OR<T extends string, P = ArbitraryPermutation<T>> = [T] extends [never]
? never
: P extends P
? P extends string[]
? JoinWith<P, 'or'>
: never
: never;
드디어 완성됐습니다.🎉유니온의 모든 요소를 포함하는 배열을 만들어서 질문 3가 따로 만드는 유형이 작용할 수 있도록!
최종 버전은 여기.
다른 해석
댓글에서 가장 우아한 해답법을 알려주셨어요.🙏
여기까지 해설을 읽으신 분들은 이해하실 거예요!
정답
type OR<T extends string, U extends string = T> = T extends T
? T | `${T}or${OR<Exclude<U, T>>}`
: never;
해법
질문 1: 유니온을 만드는 요소를 모두 or로 연결하는 유형
type JoinedWithOR<T> = ...
JoinedWithOR<"A"|"B"|"C"> // "AorBorC" | "AorCorB" | "BorAorC" | "BorCorA" | "CorAorB" | "CorBorA"
해설type JoinedWithOR<T extends string, U extends string = T> = [T] extends [never]
? never
: T extends T
? [Exclude<U, T>] extends [never]
? T
: `${T}or${JoinedWithOR<Exclude<U, T>>}`
: never;
해법 1로 키운 지식이 있으면 쉽게 이해할 수 있을 것 같아!그나저나
[Exclude<U, T>] extends [never]
진짜 T는 이게 없으면 마지막에 or가 있기 때문이야.질문 2: 유니온의 요소를 지정한 개수에 따라 연결하는 유형 만들기
type OrKeyOfLength<T, U> = ...
OrKeyOfLength<"A"|"B"|"C", 2> // "AorB" | "AorC" | "BorA" | "BorC" | "CorA" | "CorB"
해설type ArrayOfLength<N extends number, C extends any[] = []> = C['length'] extends N
? C
: ArrayOfLength<N, [...C, any]>;
type Minus<N extends number> = ArrayOfLength<N> extends [any, ...infer Rest]
? Rest['length']
: never;
type OrKeyOfLength<T extends string, Length extends number, U extends string = T> = [T] extends [
never,
]
? never
: Length extends 1
? T
: T extends T
? [Exclude<U, T>] extends [never]
? `${T}`
: `${T}or${OrKeyOfLength<Exclude<U, T>, Minus<Length>>}`
: never;
좀 복잡해졌네.하는 일 자체는 매우 간단하다. 단지 방금 한'or'연결의 귀속형을 개량하여 귀속을 진행하는 횟수를 제한할 뿐이다.다만, Type Script형의 세계에서는 숫자를 직접 줄이거나 늘릴 수는 없다.유형의 세계에서number의 유형
AorBorCor
과 유형1
은 크기와 관계가 없기 때문이다.따라서 유형의 세계에서 숫자의 증량과 증량 등은 대부분 배열의 길이로 이루어진다.숫자
2
를 길이 1의 수조로 처리하고 수조의 원소수를 증가하거나 감소시켜 숫자의 증가와 감소를 처리한다.상술한 코드는 아래와 같이 처리한다.
1
: 수신한 숫자의 길이와 같은 배열 만들기ArrayOfLength
: 수신된 어레이의 길이 감소1질문 3: Union 요소 수 이하의 비음정수 Union을 반환하는 유형 만들기
type LTEUnionLength<T> = ... // LTE : Less Than or Equal to
LTEUnionLength<"A"|"B"|"C"> // 0 | 1 | 2 | 3
해설type UnionLength<T, Length extends any[] = [], U = T> = [T] extends [never]
? Length['length'] // ここで配列の長さを返す
: T extends T
? UnionLength<Exclude<U, T>, [...Length, any]>
: never;
type LTEUnionLength<T, U = T> = [T] extends [never]
? 0
: T extends T
? UnionLength<U> | LTEUnionLength<Exclude<U, T>>
: never;
절차로서 유니온의 요소수를 구하는 유형Minus
을 제작하여 귀속적으로 사용한다.방금 작은 문제 2에서 나온 숫자를 배열 길이로 처리하는 기교도 나왔다.
질문 4:1~3에 기초하여 Union의 모든 요소를 or로 결합
type OR<T> = ...
OR<"A"|"B"|"C"> // Key | "AorB" | "AorC" | "BorA" | "BorC" | "CorA" | "CorB" | "AorBorC" | "AorCorB" | "BorAorC" | "BorCorA" | "CorAorB" | "CorBorA"
해설type OR<T extends string> = OrKeyOfLength<T, LTEUnionLength<T>>;
그냥 지금까지의 조합!최종 버전은 여기.
수수께끼를 풀다
자세히 설명한 부분이 있나 해서 수수께끼를 풀 수 있는 과정을 가볍게 잡아주면 좋을 것 같아요.
또 다른 해법이 있으신 분들은 댓글로 알려주세요.🙏
끝맺다
어때요?
이번 편은 퍼즐로 바뀌었지만 라이브러리 사람들도 좋아하면 만질 수 있다면 기쁠 것 같아요.
Reference
이 문제에 관하여(리액트로 정렬하거나 줄이려는 당신에게~), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/kj455/articles/5985d34d0a8aa6텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)