типскрипт выводит универсальные типы из свойств

#typescript #generics #type-inference

Вопрос:

Я пытаюсь создать класс, который объединяет два других класса, имеющих один или несколько универсальных. Объединенный класс должен вывести все универсальные типы из исходных двух классов. Я попытался использовать ключевое слово infer, но я не уверен, что использую его правильно, или оно просто не сработало для меня. Кроме того, все примеры, которые я видел, выводят только один параметр универсального типа, но в моем случае мне нужно вывести несколько универсальных типов из одного типа. Пример на игровой площадке TS-это та структура, которая мне нужна, просто отсутствует вывод типа для свойств FooBar:

 class Foo<A, B> {
  constructor(public a: A, public b: B) {}
}

class Bar<C> {
  constructor(public c: C) {}
}

class FooBar <F extends Foo<any, any>, B extends Bar<any>> {

  // How do I infer these properties?
  a: any;
  b: any;
  c: any;

  constructor(foo: F, bar: B) {
    this.a = foo.a;
    this.b = foo.b;
    this.c = bar.c;
  }
}

const foo = new Foo(1, 'two');
foo.a // ts knows this is 'number'
foo.b // ts knows this is 'string'

const bar = new Bar(true);
bar.c // ts knows this is 'boolean'

const foobar = new FooBar(foo, bar);
foobar.a // this type is now 'any'
foobar.b // this type is now 'any'
foobar.c // this type is now 'any'
 

Ответ №1:

 class FooBar <F extends Foo<any, any>, B extends Bar<any>> {

  a: F['a'];
  b: F['b'];
  c: B['c'];

  constructor(foo: F, bar: B) {
    this.a = foo.a;
    this.b = foo.b;
    this.c = bar.c;
  }
}
 

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

1. Спасибо, я только что понял, что это отвечает на заданный вопрос — однако он напрямую выводит свойство класса, а не общее, что я и ищу. Основной пример, который я сделал, позволил использовать более простой метод извлечения типа, но в моем реальном случае я не могу получить доступ к типу из свойства — это просто универсальный, на который ссылаются как на возвращаемые значения. Можно ли обновить этот ответ, чтобы отразить прямое получение универсального без доступа к типу свойства?

2. Поразмыслив — этот ответ очень полезен для того, как я сформулировал вопрос — я обновлю название, оставлю это и задам новый вопрос.