Strongly type `Listener`

Don't use `Function` as it allows any sort of calling pattern
pull/66115/head
Matt Bierner 2019-01-03 15:51:45 -08:00
parent af35040758
commit 6d680a040f
3 changed files with 14 additions and 8 deletions

View File

@ -355,7 +355,7 @@ export namespace Event {
}
}
type Listener = [Function, any] | Function;
type Listener<T> = [(e: T) => void, any] | ((e: T) => void);
export interface EmitterOptions {
onFirstListenerAdd?: Function;
@ -466,8 +466,8 @@ export class Emitter<T> {
private readonly _leakageMon: LeakageMonitor | undefined;
private _disposed: boolean = false;
private _event: Event<T> | undefined;
private _deliveryQueue: [Listener, T][] | undefined;
protected _listeners: LinkedList<Listener> | undefined;
private _deliveryQueue: [Listener<T>, T][] | undefined;
protected _listeners: LinkedList<Listener<T>> | undefined;
constructor(options?: EmitterOptions) {
this._options = options;
@ -541,7 +541,7 @@ export class Emitter<T> {
* To be kept private to fire an event to
* subscribers
*/
fire(event: T): any {
fire(event: T): void {
if (this._listeners) {
// put all [listener,event]-pairs into delivery queue
// then emit all event. an inner/nested event might be
@ -590,7 +590,7 @@ export interface IWaitUntil {
export class AsyncEmitter<T extends IWaitUntil> extends Emitter<T> {
private _asyncDeliveryQueue: [Listener, T, Promise<any>[]][];
private _asyncDeliveryQueue: [Listener<T>, T, Promise<any>[]][];
async fireAsync(eventFn: (thenables: Promise<any>[], listener: Function) => T): Promise<void> {
if (!this._listeners) {

View File

@ -252,14 +252,20 @@ class QuickInput implements IQuickInput {
this.ui.leftActionBar.clear();
const leftButtons = this.buttons.filter(button => button === backButton);
this.ui.leftActionBar.push(leftButtons.map((button, index) => {
const action = new Action(`id-${index}`, '', button.iconClass || getIconClass(button.iconPath), true, () => this.onDidTriggerButtonEmitter.fire(button));
const action = new Action(`id-${index}`, '', button.iconClass || getIconClass(button.iconPath), true, () => {
this.onDidTriggerButtonEmitter.fire(button);
return Promise.resolve(null);
});
action.tooltip = button.tooltip;
return action;
}), { icon: true, label: false });
this.ui.rightActionBar.clear();
const rightButtons = this.buttons.filter(button => button !== backButton);
this.ui.rightActionBar.push(rightButtons.map((button, index) => {
const action = new Action(`id-${index}`, '', button.iconClass || getIconClass(button.iconPath), true, () => this.onDidTriggerButtonEmitter.fire(button));
const action = new Action(`id-${index}`, '', button.iconClass || getIconClass(button.iconPath), true, () => {
this.onDidTriggerButtonEmitter.fire(button);
return Promise.resolve(null);
});
action.tooltip = button.tooltip;
return action;
}), { icon: true, label: false });

View File

@ -143,7 +143,7 @@ suite('RawSearchService', () => {
const service = new RawSearchService();
function fileSearch(config: IFileQuery, batchSize: number): Event<ISerializedSearchProgressItem | ISerializedSearchComplete> {
let promise: CancelablePromise<ISerializedSearchSuccess>;
let promise: CancelablePromise<ISerializedSearchSuccess | void>;
const emitter = new Emitter<ISerializedSearchProgressItem | ISerializedSearchComplete>({
onFirstListenerAdd: () => {