Объявите фабрику с универсальными типами из собственного класса

#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>() , поэтому важно иметь возможность вызывать фабрику без универсальных типов