#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. Поразмыслив — этот ответ очень полезен для того, как я сформулировал вопрос — я обновлю название, оставлю это и задам новый вопрос.