As a C# programming I have a lot of interest in the TypeScript project. Lately I've been playing around with it to look what it can do. I found myself in need of some event handling, so I decided to build something that looks like the event handling .Net gives you. It grew into Strongly Typed Events for TypeScript. This tutorial is part of a series.
2018-02: we've updated to a new version of the project. The article matches the latest version. Get the latest version by running: npm install strongly-typed-events --save
The IEvent<TSender, TArgs>
An event is defined as a pair of sender and event arguments. It's leveraging generics to make them strongly typed. Note: the actual interface in the project is a little bit more complex.
/** Models an event with a generic sender and generic arguments */
interface IEvent<TSender, TArgs> {
subscribe(fn: (sender: TSender, args: TArgs) => void): void;
unsubscribe(fn: (sender: TSender, args: TArgs) => void): void;
}
Example implementation: a pulse generator
Let's create a pulse generator that will trigger an event based on the given the frequency in Hertz. I'm using the EventDispatcher
from the package:
/** Models an event with a generic sender and generic arguments */
interface IEvent<TSender, TArgs> {
subscribe(fn: (sender: TSender, args: TArgs) => void): void;
unsubscribe(fn: (sender: TSender, args: TArgs) => void): void;
}
Now let's subscribe to the event and beep each time we receive a pulse.
var generator = new PulseGenerator(1);
//subscribe on the onPulse event
generator.onPulsate.subscribe((p, hz) => {
//play beep:
var snd = new Audio("data:audio/wav;base64,UklGRkYDAABXQVZFZm10IBAAAAABAAEAQB8AAIA+AAACABAAZGF0YSIDAAAAADM1FVYVVjM1AADNyuup66nNygAAMzUVVhVWMzUAAM3K66nrqc3KAAAzNRVWFVYzNQAAzcrrqeupzcoAADM1FVYVVjM1AADNyuup66nNygAAMzUVVhVWMzUAAM3K66nrqc3KAAAzNRVWFVYzNQAAzcrrqeupzcoAADM1FVYVVjM1AADNyuup66nNygAAMzUVVhVWMzUAAM3K66nrqc3KAAAzNRVWFVYzNQAAzcrrqeupzcoAADM1FVYVVjM1AADNyuup66nNygAAMzUVVhVWMzUAAM3K66nrqc3KAAAzNRVWFVYzNQAAzcrrqeupzcoAADM1FVYVVjM1AADNyuup66nNygAAMzUVVhVWMzUAAM3K66nrqc3KAAAzNRVWFVYzNQAAzcrrqeupzcoAADM1FVYVVjM1AADNyuup66nNygAAMzUVVhVWMzUAAM3K66nrqc3KAAAzNRVWFVYzNQAAzcrrqeupzcoAADM1FVYVVjM1AADNyuup66nNygAAMzUVVhVWMzUAAM3K66nrqc3KAAAzNRVWFVYzNQAAzcrrqeupzcoAADM1FVYVVjM1AADNyuup66nNygAAMzUVVhVWMzUAAM3K66nrqc3KAAAzNRVWFVYzNQAAzcrrqeupzcoAADM1FVYVVjM1AADNyuup66nNygAAMzUVVhVWMzUAAM3K66nrqc3KAAAzNRVWFVYzNQAAzcrrqeupzcoAADM1FVYVVjM1AADNyuup66nNygAAMzUVVhVWMzUAAM3K66nrqc3KAAAzNRVWFVYzNQAAzcrrqeupzcoAADM1FVYVVjM1AADNyuup66nNygAAMzUVVhVWMzUAAM3K66nrqc3KAACJNO5T2lKKMgAAys50sYeyydAAAOMtK0kYSOQrAABx1Ta8Sr1v1wAAPCdoPlU9PiUAABfc+cYMyBbeAACWIKYzkjKXHgAAveK70c/SvOQAAO8Z4yjQJ/EXAABk6X7ckd1j6wAASRMhHg0dShEAAArwQedU6AnyAACjDF4TSxKkCgAAsfYD8hfzr/gAAPwFnAiIB/0DAABX/cb82f1W/wAA");
snd.play();
});
//change frequency
setTimeout(function () {
generator.frequencyInHz = 2;
}, 3000);
More
Check out the following:
- Strongly typed event handlers in TypeScript (Part 1)
- Using strongly typed events in TypeScript with interfaces (Part 2)
- Strongly Typed Events in TypeScript using an event list (Part 3)
- Adding named events to your classes (Part 4)
- GitHub: https://github.com/KeesCBakker/Strongly-Typed-Events-for-TypeScript
I like the idea of strongly typed events (coming from C# myself) but one main purpose of events is decoupling (which .NET never cared about). So the main flaw of this library/examples I see is that you have the listener to subscribe to the source of the event.
1. Listeners should be able to subscribe to the event (without knowing anything about the source)
(because)
2. Different sources should be able to raise the same event.
(I guess this is somewhat achievable if the EventDispatcher becomes global rather than part of the source though your examples don’t demonstrate this)
Long story short this lib seems like a simulation of ASP.NET events. For actual application my recommendation would be to take from .NET only the good part (leave the .NET flaws with .NET ;) )
I agree. But it would be important to have some sort of way of detecting the source of the event. How would we distinguish between events? Later versions of the library have different dispatchers (like signals and simple events that only have data).