Разрешить только подключи объекта в качестве аргумента функции - PullRequest
0 голосов
/ 22 апреля 2020

Предположим, у нас есть такой объект:

const MyObject = {
  gloves: {
    gloves1: ...,
    gloves2: ...
  },
  boots: {
    boots1: ...,
    boots2: ...

  }
}

, где такие имена, как gloves1, являются переменными. Затем мы создаем вспомогательную функцию для получения указанного c значения из MyObject, т. Е.

function getValue(category: keyof typeof MyObject, name: string) {
 return MyObject[category][name];
}

. Есть ли способ динамического ввода name на основе того, что catefory было передано в качестве аргумента? Поэтому, если я передам gloves в качестве имени категории, должно быть только gloves1 или gloves2

Ответы [ 2 ]

1 голос
/ 22 апреля 2020

Так как пример объекта недействителен, я создам свой собственный, но не стесняйтесь заменить его:

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 ссылка на код

0 голосов
/ 22 апреля 2020

Ваш пример объекта поврежден:

const MyObject = {
    gloves: {
        gloves1: 1,
        gloves2: 2
    },
    boots: {
        boots1: 3,
        boots2: 4
    }
}

С генериками:

function getValue<Category extends keyof typeof MyObject>(category: Category, name: keyof typeof MyObject[Category]) {
    return MyObject[category][name];
}
getValue("boots", "gloves1"); // Argument of type '"gloves1"' is not assignable to parameter of type '"boots1" | "boots2"'.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...