Как получить тип каждого элемента записи в typescript?

#typescript #typescript-typings

#typescript #typescript-типизации

Вопрос:

Я гуглю ответ, но все еще не нашел его. Итак, я должен опубликовать это здесь.

Проблема довольно проста:

Допустим, у меня есть запись любого абстрактного класса.

 const record = Record<string, Model>
  

И у меня также есть несколько реализаций моей модели:

 class A extends Model {
  foo() {
    return 'foo';
  }
}

class B extends Model {
  bar() {
    return 'bar';
  }
}
  

и затем я сохраняю свои модели в своей записи:

 record.classA = new A();
record.classB = new B();
  

Как мы можем видеть, свойства в моей записи являются динамическими.

Итак, вопрос в следующем: возможно ли получить тип каждого ключа и всех ключей моей модели?

Например, я хочу иметь что-то вроде этого:

 function get(key: string) {
  return record[key]; //Here I expect to receive a correct type (for example class A or class B regarding the key)
}
  

И еще один вопрос: возможно ли получить все существующие ключи, когда я нажимаю enter после «record».?

Я читал о перегрузке функций, но может быть другое решение или я могу динамически перегружать свои функции? Я хочу создать структуру модуля для моего приложения.

Большое спасибо!

С уважением, Дмитрий

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

1. Это можно сделать, только если вы готовы инициализировать record все сразу с помощью объектного литерала

2. Не совсем понятно, что вы подразумеваете под «получить тип», но если вы можете просто инициализировать объект известными ключами — typescript сам определит типы typescriptlang.org/play ? #code/…

3. ( const record = Record<string, Model> Я предполагаю, что должно быть const record: Record<string, Model> = {}; )

Ответ №1:

Typescript — это язык со статической типизацией. Это означает, что если вы определяете record как Record<string, Model> . Все его ключи всегда будут иметь тип Model .

Если вы хотите иметь более сложный тип. Вы должны определить его либо с помощью generic, либо заранее.

 const record = {
  classA: new A(),
  classB: new B(),
}
  

Для общего использования потребуется оболочка

 class RecoldHolder<T extends Record<string, Model>> {
  record: T;

  get<K extends keyof T>(key: K): T[K] {
    return this.record[key];
  }
}
  

PS: Никогда не используйте ключевые слова в качестве имен функций, иногда вы столкнетесь с действительно странным поведением. Используйте getter , вместо get и т.д.