То, что вы ищете, это ограниченные дженерики.Они объяснены в документации Flow здесь .
Во-первых, сделайте весь класс универсальным для некоторого типа T
, а не только для отдельных методов.Затем прикрепите границу (аннотацию типа) к типу T
, где она объявлена в верхней части класса, например:
class EventUtility<T: PartyEvent | AppointmentEvent | MealEvent> {
Теперь ваш класс примет некоторый тип T
, но толькоесли T
совпадает с той границей, которую вы ему дали.Вы можете делать вещи только со значением типа T
внутри, которые разрешены для значения, тип которого является типом границы, и любой тип T
, используемый для создания экземпляра класса, будет того же типа, который будетиспользоваться для возвращаемых значений.
Вторая задача - как убедиться, что в вашем классе одновременно хранится только один вид событий.Это сложно, потому что тип T
является типом объединения, то есть может быть любым из трех.Поток позволит вам создать экземпляр класса с массивом объектов PartyEvent
, в этом случае T
будет иметь тип PartyEvent
, но он также позволит вам создать его с массивом объектов MealEvent
и AppointmentEvent
в этом случае T
будет иметь тип MealEvent | AppointmentEvent
.Вы можете обойти это, предоставив явную аннотацию типа, где вы используете EventUtility
, указав, какой тип вы хотите, чтобы он содержал.Даже несмотря на то, что Flow позволит вам создать экземпляр EventUtility
с комбинацией типов, он выдаст ошибку, если вы создадите экземпляр с типом большего размера, чем вы объявили в явной аннотации.
Вот решениек вашему примеру на игровой площадке Flow.Попробуйте создать класс с разными границами для T
и раскомментировать некоторые вызовы, чтобы увидеть, какие ошибки появляются.Использование { startTime: Date }
в качестве границы для T
должно дать вам тот же результат.