개체의 최상위 수준과 개체의 가장 깊은 수준에 키를 입력 한 약간 복잡한 개체가 있으며 개체의 두 번째 입력 키를 인덱싱 할 수없는 것 같습니다.
이것은 내 개체와 내 인터페이스 (간체)입니다.
const obj = {
keyA: {
variants: {
"0": false,
"1": false
}
},
keyB: {
variants: {
"0-0": false,
"0-1": false
}
}
}
type Obj = typeof obj;
type ObjKeys = keyof Obj;
type ObjVariants<T extends ObjKeys> = Obj[T]["variants"];
을 (를) selectedKeys.variant
사용하여 제대로 인덱싱 할 수없는 함수입니다 defaultVariant
.
function getVariant<T extends ObjKeys>(key: T, defaultVariant: keyof ObjVariants<T>) {
const selectedKey = obj[key];
const selectedVariant = selectedKey.variants[defaultVariant];
}
내가 얻는 오류는 다음과 같습니다.
Type 'keyof { keyA: { variants: { 0: boolean; 1: boolean; }; }; keyB: { variants: { "0-0": boolean; "0-1": boolean; }; }; }[T]["variants"]' cannot be used to index type '{ 0: boolean; 1: boolean; } | { "0-0": boolean; "0-1": boolean; }'.(2536)
https://github.com/microsoft/TypeScript/issues/21760 및 https://github.com/microsoft/TypeScript/issues/36631의 두 가지 문제와 관련된 것 같습니다. 하지만 " 해결 방법 "이 저에게 효과적입니다. 뭔가 놓친 것 같습니다.
다른 사람이 비슷한 것을 경험했거나 제안 된 해결 방법이 있습니까?
PD : I로는 엄격한 타입을 추가하는 시도 obj
하고 사용하는 것과 동일한 결과를 발견 typeof obj
.
디자인에 의한 동작, 즉 디자인 제한처럼 보입니다. 이러한 함수는 하위 유형도 전달할 수 있으므로 유형 안전하기가 어렵습니다. 예를 들어 T extends ObjKeys
union을 다룹니다. keyA | keyB
이는이 제약 조건이 변형 중 하나라고 가정 할 수 없음을 의미합니다.
제약 조건을 완전히 설정하기 위해 다음 접근 방식으로 이동할 수 있습니다.
function getVariant
<O extends { [K in K1]: { variants: { [KK in K2]: Obj[K1]["variants"][KK] } } }
, K1 extends keyof Obj
, K2 extends keyof Obj[K1]["variants"]>
(o: O, key: K1, defaultVariant: K2) {
const selectedKey = o[key].variants;
const selectedVariant = selectedKey[defaultVariant];
}
// using
getVariant(obj, 'keyA', '0')
보시다시피 키 K1
및 의 유형을 좁히기 위해 추가 매개 변수를 만들었습니다 K2
. 가장 중요한 라인은 { [K in K1]: { variants: { [KK in K2]: Obj[K1]["variants"][KK] } } }
입니다. 그것은 우리가 두 키를 모두 다루는 유형을 다루지 만 정의는 여전히 우리 obj
유형 과 호환된다는 것을 의미합니다 .
우리는 여전히 obj
외부 상수로 사용할 수 있지만 유형 어설 션을 사용해야합니다.
function getVariant<K1 extends keyof Obj, K2 extends keyof Obj[K1]["variants"]>
(key: K1, defaultVariant: K2) {
let _obj = obj as { [K in K1]: { variants: { [KK in K2]: Obj[K1]["variants"][KK] } } };
const selectedKey = _obj[key].variants;
const selectedVariant = selectedKey[defaultVariant];
}
// using
getVariant('keyA', '0')
이것이 작동하는 이유는 무엇입니까? 우리가 가지고 있거나 가질 정확한 유형으로 유형을 정적으로 설정하기 때문에 작동합니다. T extends A
T가 A라는 것을 의미하지 않는다고 말하면 T가 A의 일부 변형이라는 의미도 아닙니다. T extends A
우리가 좁히고 T
할당 가능한 유형 을 제한 한다고 해서 A
엄격하지 않습니다. 유형을 만들면 유형 {[K in T]: X}, T extends Y
이의 정확한 키를 가지며 T
가능한 할당 가능한 유형에서에 대해 엄격하게 하나의 유형이 될 것임을 엄격하게 정의합니다 Y
. 이러한 엄격한 정의는 같은 정적 값을 설정하는 것과 같습니다 Obj['keyA']
.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다