유형 스크립트:튜플 유형에서 항목 제거
이것이 가능한지는 확실하지 않지만 다음과 같은 튜플을 변환하는 유형을 정의할 수 있습니다.[number, string, undefined, number]
로.[number, string, number]
(필터 아웃)undefined
).
저는 이런 것에 대해 생각했습니다.
type FilterUndefined<T extends any[]> = {
[i in keyof T]: T[i] extends undefined ? /* nothing? */ : T[i];
}
슬프게도 저는 이것을 성취할 방법이 없다고 꽤 확신합니다.
알겠습니다! 하지만 재귀 마법이 많이 필요합니다.
type PrependTuple<A, T extends Array<any>> =
A extends undefined ? T :
(((a: A, ...b: T) => void) extends (...a: infer I) => void ? I : [])
type RemoveFirstFromTuple<T extends any[]> =
T['length'] extends 0 ? undefined :
(((...b: T) => void) extends (a, ...b: infer I) => void ? I : [])
type FirstFromTuple<T extends any[]> =
T['length'] extends 0 ? undefined : T[0]
type NumberToTuple<N extends number, L extends Array<any> = []> = {
true: L;
false: NumberToTuple<N, PrependTuple<1, L>>;
}[L['length'] extends N ? "true" : "false"];
type Decrease<I extends number> = RemoveFirstFromTuple<NumberToTuple<I>>['length']
type H = Decrease<4>
type Iter<N extends number, Items extends any[], L extends Array<any> = []> = {
true: L;
false: Iter<FirstFromTuple<Items> extends undefined ? Decrease<N> : N, RemoveFirstFromTuple<Items>, PrependTuple<FirstFromTuple<Items>, L>>;
}[L["length"] extends N ? "true" : "false"];
type FilterUndefined<T extends any[]> = Iter<T['length'], T>
type I = [number, string, undefined, number];
type R = FilterUndefined<I>
작동 방식:
PrependToTuple은 항목을 가져오는 유틸리티입니다.A
및 목록T
그리고 그것을 1등에 추가합니다.A
정의되지 않았습니다. PrependToTuple<undefined, []> => []
,PrependToTuple<undefined, [number]> => [number]
RemoveFirstFromTuple
같은 방식으로 꽤 많이 작동합니다.
NumberToTuple
최종 튜플의 길이가 다음인지 재귀적으로 확인합니다.N
그렇지 않은 경우 재귀 호출에 1을 추가합니다.이 사용률은 다음을 생성하는 데 필요합니다.Decrease
실용적인
그리고 가장 중요한 z.Iter
최종 튜플의 길이가 다음과 같을 때 재귀 루프와 같이 작동합니다.N
(크기:Input
그것의 반환.Output
,그렇지만PrependToTuple
우리가 추가하려고 할 때 길이가 늘어나지 않습니다.undefined
그래서 언제Iter<FirstFromTuple<Items> extends undefined
우리는 N을 줄여야 합니다.
TS 4.1
이제 튜플에 대한 필터 작업이 공식적으로 가능합니다.
type FilterUndefined<T extends unknown[]> = T extends [] ? [] :
T extends [infer H, ...infer R] ?
H extends undefined ? FilterUndefined<R> : [H, ...FilterUndefined<R>] : T
Let's do some tests to check, that it is working as intended:
type T1 = FilterUndefined<[number, string, undefined, number]>
// [number, string, number]
type T2 = FilterUndefined<[1, undefined, 2]> // [1, 2]
type T3 = FilterUndefined<[undefined, 2]> // [2]
type T4 = FilterUndefined<[2, undefined]> // [2]
type T5 = FilterUndefined<[undefined, undefined, 2]> // [2]
type T6 = FilterUndefined<[undefined]> // []
type T7 = FilterUndefined<[]> // []
추가 정보
보충 답변:
ford04의 답변에 있는 접근 방식의 확장을 통해 임의의 인덱스에서 값을 제거할 수 있는 "스플라이어" 유틸리티 유형을 만들 수 있습니다(유형 안전에 대한 솔루션을 찾는 사람이 있을 경우).splice
).
여기에는 튜플을 생성할 유틸리티 유형을 생성하는 작업이 포함됩니다.undefined
지정된 튜플 및 인덱스에서:
type UndefIndex<T extends any[], I extends number> = {
[ P in keyof T ] : P extends Exclude<keyof T, keyof any[]> ? P extends `${I}` ? undefined : T[P] : T[P]
}
그렇다면 이건 단지 구성의 문제일 뿐입니다.UndefIndex
그리고.FilterUndefined
유형:
type FilterUndefined<T extends any[]> = T extends [] ? [] :
T extends [infer H, ...infer R] ?
H extends undefined ? FilterUndefined<R> : [H, ...FilterUndefined<R>] : T;
type SpliceTuple<T extends any[], I extends number> = FilterUndefined<UndefIndex<T, I>>;
type a = SpliceTuple<[1,2,3], 0>; //[2,3]
type b = SpliceTuple<[1,2,3], 1>; //[1,3]
type c = SpliceTuple<[1,2,3], 2>; //[1,2]
type d = SpliceTuple<[1,2,3], 3>; //[1,2,3]
언급URL : https://stackoverflow.com/questions/54607400/typescript-remove-entries-from-tuple-type
'programing' 카테고리의 다른 글
SQL Server에서 작은 따옴표 바꾸기 (0) | 2023.07.15 |
---|---|
Excel VBA에서 구현체를 사용하는 방법 (0) | 2023.07.15 |
R의 축 레이블 회전 (0) | 2023.07.10 |
루비의 나눗셈이 십진수 값이 아닌 정수를 반환하는 이유는 무엇입니까? (0) | 2023.07.10 |
경로 전환 시 Vuex 재설정 저장소 변수 (0) | 2023.07.10 |