Repository navigation
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
Activity
dardino commentedon Apr 10, 2017
it's like this: #15098 with
?AdamWillden commentedon Apr 10, 2017
Andy (Andrewkraft) (@Andy-MS), yes.
Gabriele (@dardino), not quite. My code is already ensuring that it is not undefined I don't want users of the code to have to handle (again) the null/undefined cases.
DanielRosenwasser commentedon Apr 13, 2017
Sounds like a duplicate of #14366.
AdamWillden commentedon Apr 13, 2017
Daniel Rosenwasser (@DanielRosenwasser) yes, I think it might be. It's not immediately obvious but yes.
I might still have a draft on my tablet at home about a more generic suggestion of a 'strip' operator. I was going to suggest that for a more generic solution we could do something like:
Although I'm not sure how much scope or requirement there is for such a thing.
AdamWillden commentedon Apr 13, 2017
Here's what I had written
In generic terms, to provoke some thought (if easier to implement), I'm after something that can strip a type from an existing compound type.
Given we have
&=andand|=orwe could add^=stripgcnew commentedon Apr 14, 2017
Subtraction types have already been proposed several times. See #4183
AdamWillden commentedon Apr 14, 2017
Right then. Closing and subscribing to those issues. Thanks everyone.