반응형
TypeScript 매핑된 유형의 역을 얻으려면 어떻게 해야 합니까?
나는 TypeScript 맵핑 타입의 "역"을 찾고 있다. (그 속성은 엄격하게 문자열이므로 "불가역"이다.). 내가 원하는 결과를 설명하기 위해, 나는 일반적인 것이 필요하다
type Inverse<M> = ...
변신할 수 있다
type MappedType = {
key1: 'value1'
key2: 'value2'
};
안으로
/**
* {
* value1: 'key1';
* value2: 'key2';
* }
*/
type MappedTypeInverse = Inverse<MappedType>
벌써 몇 가지 시도를 해봤는데.. 그러나 소용이 없었다:
type Inverse<M> = M extends Record<infer O, infer T> ? Record<T, O> : never;
/**
* type MappedTypeInverse = {
* value1: 'key1' | 'key2'
* value2: 'key2' | 'key2'
* }
*/
type MappedTypeInverse = Inverse<MappedType>
type InverseValue<M extends Record<any, any>, V extends M[keyof M]> = V extends M[infer K] ? K : never;
/**
* type MappedTypeInverseValue = unknown // expecting 'key1'
*/
type MappedTypeInverseValue = InverseValue<MappedType, 'value1'>
이게 가능하기나 해요? 어떤 도움이라도 감사하겠습니다!
이를 달성할 수 있는 방법은 다음과 같습니다. 이 과정의 중간 단계에서 조합을 교차로로 변환하기 위해 에서 일부 "악마술"을 차용한다:
type MappedType = {
key1: 'value1';
key2: 'value2';
};
type Intermediate<R extends Record<string, string>> =
R extends Record<infer K, string>
? { [P in K]: { [Q in R[P]]: P; }; }
: never;
type UnionToIntersection<U> =
(U extends any ? (k: U) => void : never) extends ((k: infer I) => void)
? I
: never;
type Inverse<R extends Record<string, string>> =
Intermediate<R> extends Record<string, infer T>
? { [K in keyof UnionToIntersection<T>]: UnionToIntersection<T>[K]; }
: never;
type InverseMappedType = Inverse<MappedType>;
// type InverseMappedType = {
// value1: 'key1';
// value2: 'key2';
// }
이 방법의 또 다른 이점은 입력 레코드에 중복된 속성 값이 포함되어 있을 때 적절한 속성 값을 가진 매핑된 유형을 출력한다는 것입니다:
type MappedType = {
key1: 'value1';
key2: 'value1' | 'value2';
};
type InverseMappedType = Inverse<MappedType>;
// type InverseMappedType = {
// value1: never;
// value2: 'key2';
// }
TypeScript에 나보다 더 정통한 사람은 매핑된 유형을 반전시키는 이것보다 더 짧은 방법을 알고 있을 수 있지만, 이것은 적어도 그 일을 해내는 것처럼 보인다.
다음은 (패트릭 로버트의 좋은 해결책 외에도) 기울어진 부분입니다:
type KeyFromVal<T, V> = {
[K in keyof T]: V extends T[K] ? K : never
}[keyof T];
// we assume the type to be an object literal with string values
// , should also work with number or symbol
type Inverse<M extends Record<string, string>> = {
[K in M[keyof M]]: KeyFromVal<M, K>
};
type MappedType = {
key1: 'value1'
key2: 'value2'
};
type MappedTypeInverse = Inverse<MappedType> // { value1: "key1"; value2: "key2"; }
연산자와 함께 매핑된 유형을 사용할 수 있습니다.
type Inverse<T> = {[K in keyof T as (T[K] & (string | number))]: K};
반응형
'개발하자' 카테고리의 다른 글
Go_router에서 탐색 모음을 사용하는 방법은 무엇입니까? | 펄럭이다 (0) | 2023.01.11 |
---|---|
Visual Studio 코드(플리터)의 build.gradle 오류 (0) | 2023.01.11 |
형식 스크립트: 모듈 외부에서 가져오기 문을 사용할 수 없습니다 (0) | 2023.01.09 |
VS 코드에서 커널 - 주피터를 시작하지 못했습니다 (0) | 2023.01.09 |
주피터 노트북에서 대시 실행 문제 (0) | 2023.01.08 |