Использование универсальных типов с классом - PullRequest
0 голосов
/ 05 марта 2019

Я использую Flow и у меня есть вариант использования для универсальных типов, но я не знаю, как их использовать.

У меня есть класс, который принимает массив событий одного типа.Все типы событий имеют одни свойства (например, startTime), но отличаются от других.Возвращаемое значение для функций класса должно быть того же типа, что и события, передаваемые в массиве конструктора.

Чтобы сделать это более конкретно, в приведенном ниже коде я хотел бы оговорить, что если вы создаете экземпляр EventUtility с массивом PartyEvent с, тогда, когда вы спросите EventUtility.earliestEvent(), вы можете быть уверены, что получите PartyEvent обратно.(Массив, передаваемый в конструктор, не может состоять из смеси объектов разных типов.)

Спасибо.

export class EventUtility {
    // pick item based on JSON-friendly conditional notation
    events: Array<PartyEvent | AppointmentEvent | MealEvent>

    constructor(events: Array<PartyEvent | AppointmentEvent | MealEvent>) {
        this.events = events;
    }

    earliestEvent(): PartyEvent | AppointmentEvent | MealEvent {
        // determine earliest event in array and return it
        return event;
    }
}

1 Ответ

0 голосов
/ 05 марта 2019

То, что вы ищете, это ограниченные дженерики.Они объяснены в документации 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 должно дать вам тот же результат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...