Комментарии 16
Интересно. Пишите еще. Особенно про управление памятью ).
А нельзя ли как-то указать что тип Options — это параметрический тип Callback?
Развернутый ответ в Части 2.5
А почему класс события параметризируется типом Callback'a? Почему бы не параметризовать его типа данных, с которыми вызывается callback? Типа того:
interface IEvent<Data> {
on(fn:(Data) => boolean): ISubscribe { }
trigger(d: Data): boolean { }
}
Жаль, мне кармы не хватает, чтобы вам ее поднять. Хоть кто-то заметил.
Будет часть 2.5 с исправлением. Там все чуть сложнее, чем вы написали. Сам только утром увидел. Клятвенно обещаюсь больше на ночь глядя сложные статьи не писать.
Будет часть 2.5 с исправлением. Там все чуть сложнее, чем вы написали. Сам только утром увидел. Клятвенно обещаюсь больше на ночь глядя сложные статьи не писать.
Нет, пишите; лучшее — враг хорошего и велика вероятность, что статья так и не была бы написана.
А я уж думал, что это какая-то особая типовая дотнет-магия, которую нам, html-программистам, не понять :)
Магия есть. И не мало. См. Часть 2.5. Но ничего, что было бы за пределами понимания :)
Круто! Сам параллельно прохожу аналогичный процесс разработки.
По коду: лучше бы не писать аннотацию типа там, где она очевидна, например: «public MessagesLoaded: Events.Event = new Events.Event(); », и уж тем паче с обобщенными типами.
По коду: лучше бы не писать аннотацию типа там, где она очевидна, например: «public MessagesLoaded: Events.Event = new Events.Event(); », и уж тем паче с обобщенными типами.
В итоге тоже к этому пришел. TS без проблем по правой части выражения вычисляет. В любом случае, спасибо за замечание.
И не только по правой части. Я себе реализовал аналог
Где и в последней строчке TS знает правильный тип
Linq
и при этом получается вот такой типизированный код на TS: data.document.p.where(paragraphCondition)
.selectMany(p => p.s.where(sentenceCondition))
.selectMany(s => s.l)
.select(l => data.vocabularyItems.firstOrDefault(vi => matchesLexem(vi, l)))
.where(vocabularyLexem => vocabularyLexem && vocabularyLexem.level < 10 && !alreadyPresent(vocabularyLexem))
.distinct(vocabularyLexem => vocabularyLexem.descriptor.presentation)
.foreach(vocabularyLexem => this.vocabularyItems.push(vocabularyLexem));
Где и в последней строчке TS знает правильный тип
vocabularyLexem
. Честно говоря, тут уже рождается вопрос про велосипеды и их изобретение. А зачем в TS/JS LINQ? Сто лет есть underscore.js, который все тоже самое делает, типизирован в TS 0.9 и понятен любому фронтэнд разработчику.
Да, наверное :) Я не фронтенд-разработчик, ну и тут дело вкуса, есть и других портов Linq куча.
Не сказал бы, что совсем уж вкуса. При переносе каких-то решений из мира .Net в веб есть один очень серьезный подводный камень — в JS нет типов и, как следствие, рефлексии.
Поэтому если LINQ долежен переноситься вполне адекватно, т.к. это чисто compile time, то многие другие, опирающиеся на рефлексию подсистемы нет. Например, при все схожести шаблонизации ASP.Net MVC c underscore.template по своему подходу, перенести те же практики «в лоб» проблематично из-за невозможности использовать рефлексию для определения типов полей модели, и, как следствие, перехода к куда более тяжелому синтаксису, вместо Html.EditorFor. Хотя о моих размышлениях на эту тему скорее всего как раз следующая статья и будет.
Поэтому если LINQ долежен переноситься вполне адекватно, т.к. это чисто compile time, то многие другие, опирающиеся на рефлексию подсистемы нет. Например, при все схожести шаблонизации ASP.Net MVC c underscore.template по своему подходу, перенести те же практики «в лоб» проблематично из-за невозможности использовать рефлексию для определения типов полей модели, и, как следствие, перехода к куда более тяжелому синтаксису, вместо Html.EditorFor. Хотя о моих размышлениях на эту тему скорее всего как раз следующая статья и будет.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Построение масштабируемых приложений на TypeScript. Часть 2 — События или зачем стоит изобретать собственный велосипед