Создание динамического типа записи в TypeScript на основе значения ключа

#typescript

#typescript

Вопрос:

В настоящее время у меня есть интерфейс ниже в моем приложении. Возможно ли создать тип записи PropA на основе значения ключа. например: если я передам "apple" как ключ записи, он будет ожидать IApple интерфейс по значению, которое он ожидает IModel .

 interface Itest {
  propsA: Record<string,IModel>
}
 

Комментарии:

1. У вас должно быть сопоставление имен с типами где-то в вашем коде type Map = { apple: IApple; model: IModel } . У вас это есть?

2. Я могу добавить это сопоставление, не могли бы вы уточнить, как я могу использовать это сопоставление?

3. Когда вы говорите «передать «apple» в качестве ключа записи», что вы имеете в виду? Вы имеете в виду, что хотите, чтобы это было общим, например Itest<"apple"> , has propsA: Record<string, IApple> ? Или вы имеете в виду, что propsA сам по себе является объектом, подобным { apple: IApple; model: IModel } ? Во втором случае вам вообще не нужен Record тип. Это было бы просто interface Itest { propsA: Map } с Map подобным в предыдущем комментарии.

4. propsA: запись<string,IModel> -> если значение {string} равно «apple», IModel должен быть типом IApple, иначе IModel.

5. Это IApple подтип IModel или совершенно другой? Сложно, если они разные. Легко, если это подтип.

Ответ №1:

Вам нужен тип для объекта, в котором все string ключи имеют значение типа, за IModel исключением ключа "apple" , который имеет значение IApple .

Если IApple это подтип IModel , то это очень просто. Record<string, IModel> объявляет, что все свойства должны быть IModel . Мы объединяем это с amp; {apple?: IApple} тем, что говорит о том, что свойство apple также должно быть IApple . ? Означает, что apple это необязательно.

 interface Itest {
  propsA: Record<string, IModel> amp; {apple?: IApple}
}
 

Ссылка на игровую площадку

Если IApple и IModel являются двумя несвязанными типами, это становится сложнее, потому Record<string, IModel> что применяется ко всем string включениям apple , и мы получаем сообщение об ошибке «Свойство ‘apple’ несовместимо с подписью индекса». Нам нужно сказать, что значение IModel для каждого ключа, кроме apple .