Closed
Description
TypeScript Version: 2.3.0-dev.20170407
Code
Paste in the following code and scroll to the final two lines:
export type Subscription = { dispose: () => void };
export type SubscriberCallbacks<Events> = {
[event in keyof Events]?: Function;
};
export class Subscribers<Events extends SubscriberCallbacks<Events>> {
private subscribers: Set<Events> = new Set<Events>();
public add(events: Events): Subscription {
this.subscribers.add(events);
return this.createDisposer(events);
}
public getNotifier<EventName extends keyof Events>(eventName: EventName): Events[EventName] {
return (...args: any[]) => this.notify(eventName, ...args);
}
private notify<EventName extends keyof Events>(eventName: EventName, ...args: any[]) {
this.getReleventSubscribers(eventName).forEach((callback: Function) => callback(...args));
}
private createDisposer(events: Events) {
return { dispose: () => this.subscribers.delete(events) };
}
private getReleventSubscribers(eventName: keyof Events): Array<Events[keyof Events]> {
return Array.from(this.subscribers)
.map(events => events[eventName])
.filter(callback => typeof callback !== 'undefined');
}
}
interface TestEvents extends SubscriberCallbacks<TestEvents> {
foo?: (bar: number) => void,
baz?: (qux: string) => void,
}
let testEventSubScribers = new Subscribers<TestEvents>();
testEventSubScribers.add({
foo: (bar: number) => { console.log(bar); },
});
testEventSubScribers.add({
foo: (bar: number) => { console.log(bar + 'hi'); },
baz: (qux: string) => { console.log(qux + 'hi'); },
});
testEventSubScribers.getNotifier('foo')(2);
testEventSubScribers.getNotifier('baz')('lala');
To remove the errors I need to assert that the result of the getNotifier call is not undefined.
testEventSubScribers.getNotifier('foo')!(2);
testEventSubScribers.getNotifier('baz')!('lala');
Desired behavior:
It'd be nice if I could declare getNotifier as follows (note the final !
):
export class Subscribers<Events extends SubscriberCallbacks<Events>> {
public getNotifier<EventName extends keyof Events>(eventName: EventName): Events[EventName]! {
return (...args: any[]) => this.notify(eventName, ...args);
}
}
Metadata
Metadata
Assignees
Labels
No labels