Используйте интерфейс машинописного текста и абстрактный класс без указания общих типов

Я создал интерфейс и абстрактный класс в следующих строках:

interface ITest<A, B> {
    testFunc: (input: A) => B;
}

abstract class AClass<A, B> {
    abstract testFunc: (input: A) => B;
}

У меня есть несколько подклассов, которые расширяют AClass, и несколько объектов, реализующих ITest, с использованием различных типов для A и B. Например:

class SubClass1 extends AClass<number, string> {...}
class SubClass2 extends AClass<string[], boolean> {...}

Для абстрактного класса или интерфейса я предположил, что смогу объявить переменные, которые могут содержать эти типы без конкретных параметров универсального типа, поскольку я просто хочу, чтобы он был экземпляром AClass без учета общих типов, в следующих строках:

let aClass: AClass; // Could hold SubClass1 or SubClass2
let iTests: ITest[];

Но я получаю сообщение об ошибке, в котором говорится, что моему универсальному типу требуются два параметра типа. Единственный способ обойти это - установить параметр типа по умолчанию и / или объявить эти переменные с any в качестве аргумента общего типа (например, ITest<any, any>[])?


person Wrokar    schedule 08.09.2019    source источник
comment
Какие значения вы присваиваете aClass и iTests, но не знаете, какие конкретные типы использовать? Просто чтобы гарантировать, что мы дадим наилучшие ответы, которые мы можем.   -  person T.J. Crowder    schedule 08.09.2019
comment
@ T.J.Crowder Я отредактировал свой ответ, чтобы добавить больше контекста   -  person Wrokar    schedule 08.09.2019


Ответы (1)


Вы должны использовать любые конкретные типы, которые используются в том, на что ссылаются aClass и iTests. Если они собираются ссылаться на разные типы в разное время, вы должны использовать объединение, в котором перечислены типы, на которые они могут ссылаться. Например, если aClass может потребоваться ссылка на экземпляр SubClass1 или экземпляр SubClass2, тогда:

let aClass: SubClass1 | SubClass2;

any, any - это наихудший случай, когда вы вообще не знаете, какие могут быть конкретные типы.

Вы сказали, что у вас их более 10. Если вам действительно нужно использовать одну переменную, которая может ссылаться на экземпляры любого из этих 10+ классов, вероятно, стоит определить тип объединения:

type AnySubClass = SubClass1 | SubClass2 | SubClass3/*...*/;

... а затем использовать это для aClass.

person T.J. Crowder    schedule 08.09.2019
comment
У меня может быть более 10 подклассов, расширяющих AClass, каждый со своими уникальными типами. Таким образом, тип объединения с таким количеством опций выглядит немного грязным, но any, any тоже. Может быть, это признак того, что есть лучший способ разработать то, что я пытаюсь реализовать. - person Wrokar; 08.09.2019
comment
@Wrokar - Может быть. (Я обновил ответ.) По крайней мере, с профсоюзом, который, как вы знаете, вы случайно не обратитесь к чему-то, что не входит в эти 10+ ... - person T.J. Crowder; 08.09.2019