#typescript #generics #factory
Вопрос:
Я пытаюсь объявить (только интерфейс) фабрику, которая предоставляет любые универсальные типы из собственного класса в результат.
Сначала я объявляю какие-либо классы. Foo
является базовым классом. Moo
это какой-то пользовательский класс.
declare module 'any-module' {
class Foo<T> {
get test(): T;
}
class Moo<T> extends Foo<T> {
get moo(): T;
}
}
Затем я пытаюсь объявить фабрику, о которой знаю Foo
, но о которой не знаю Moo
. Эта фабрика должна быть производственными Foo
классами по экземпляру из расширений Foo
( Moo
например).
interface IFactory<T> {
create(Instance) => ??? /* like: new Instance<T>() */
}
Итак, я испробовал любые способы для этого:
interface IFactory<T> {
create1<R extends Foo<T>>(instance: new (...ars: any) => R): R;
create2<X extends new (...ars: any) => Foo<T>>(instance: X): InstanceType<X>;
}
но ни один из вышеперечисленных способов не работает правильно
// Getting factory with string generic
const factory = {} as IFactory<string>;
factory.create1(Moo) // Generic type is string, but result is Foo
factory.create2(Moo) // Result is Moo, but generic type is unknown
Спасибо!
Комментарии:
1.
get test(): T;
это синтаксис ivalid. Вы пытаетесь определитьmoo
геттер для свойства несуществования. Пожалуйста, исправьте свой пример2. Привет! На самом деле это не ошибка. Это объявление TS для существующего модуля. Я сделал некоторые исправления в примере. Спасибо за записку.
3. Это будет работать , если вы явно укажете универсальный тип:
factory.create1<Moo<string>>(Moo);
или укажите тип переменной:var moo: Moo<string> = factory.create(Moo);
.4. Да, это так. Но главная проблема заключается в непоследовательности одного из них. Например, если я создам фабрику со строковым типом, я совершу ошибку, когда буду звонить
create
с другим типом , напримерcreate<number>()
, поэтому важно иметь возможность вызывать фабрику без универсальных типов