Так как пример объекта недействителен, я создам свой собственный, но не стесняйтесь заменить его:
const MyObject = {
a: { b: "", c: 1, d: true },
e: { f: false, g: 2, h: "x" }
};
type MyObject = typeof MyObject; // for convenience
Правильный способ сделать это - сделать getValue()
a generi c функция. Предполагая, что некоторые из вложенных свойств относятся к разным типам, вы также хотели бы, чтобы getValue()
возвращал тип, соответствующий конкретному подвойству. Если это так, то вам нужны два обобщенных параметра c: один соответствует category
, а другой соответствует name
. Вот как вы могли бы напечатать это:
function getValue<K extends keyof MyObject, K2 extends keyof MyObject[K]>(
category: K, name: K2) {
return MyObject[category][name];
}
Теперь он компилируется без ошибок. K
является ключом MyObject
. И K2
ограничен ключом MyObject[K]
, тип поиска , соответствующим свойству MyObject
в индексе K
.
Давайте посмотрим, работает ли он:
const good1 = getValue("a", "c"); // number
const good2 = getValue("e", "h"); // string
const bad1 = getValue("a", "h"); // error!
// ----------------------> ~~~
// "h" is not assignable to "b" | "c" | "d"
Хорошо выглядит. Обратите внимание, что типы good1
и good2
отличаются и соответствуют конкретным типам MyObject.a.c
и MyObject.e.h
соответственно. И вы получите желаемую ошибку с bad1
при использовании недопустимого ключа подпробы.
Хорошо, надеюсь, это поможет!
Playground ссылка на код