refactor: `EventEmitter` to retain behaviour of pre TypeScript 3.9 (#36989)

TypeScript 3.9 introduced a breaking change where extends `any` no longer acts as `any`, instead it acts as `unknown`.

With this change we retain the behavior we had with TS 3.8 which is;

When using the `EventEmitter` as a type you must always provide a  type;
```ts
let emitter: EventEmitter<string>
```

and when initializing the `EventEmitter` class you can either provide a  type or or use the fallback type which is `any`

```ts
const emitter = new EventEmitter(); // EventEmitter<any>
const emitter = new EventEmitte<string>(); // EventEmitter<string>
``

PR Close #36989
This commit is contained in:
Alan Agius 2020-05-13 10:45:46 +02:00 committed by Kara Erickson
parent 24ec5235a0
commit f97d8a9cbd
2 changed files with 36 additions and 13 deletions

View File

@ -313,12 +313,18 @@ export declare class ErrorHandler {
handleError(error: any): void; handleError(error: any): void;
} }
export declare class EventEmitter<T> extends Subject<T> { export declare interface EventEmitter<T> extends Subject<T> {
constructor(isAsync?: boolean); new (isAsync?: boolean): EventEmitter<T>;
emit(value?: T): void; emit(value?: T): void;
subscribe(generatorOrNext?: any, error?: any, complete?: any): Subscription; subscribe(generatorOrNext?: any, error?: any, complete?: any): Subscription;
} }
export declare const EventEmitter: {
new (isAsync?: boolean): EventEmitter<any>;
new <T>(isAsync?: boolean): EventEmitter<T>;
readonly prototype: EventEmitter<any>;
};
export declare interface ExistingProvider extends ExistingSansProvider { export declare interface ExistingProvider extends ExistingSansProvider {
multi?: boolean; multi?: boolean;
provide: any; provide: any;

View File

@ -61,32 +61,26 @@ import {Subject, Subscription} from 'rxjs';
* @see [Observables in Angular](guide/observables-in-angular) * @see [Observables in Angular](guide/observables-in-angular)
* @publicApi * @publicApi
*/ */
export class EventEmitter<T> extends Subject<T> { export interface EventEmitter<T> extends Subject<T> {
/** /**
* @internal * @internal
*/ */
__isAsync: boolean; // tslint:disable-line __isAsync: boolean;
/** /**
* Creates an instance of this class that can * Creates an instance of this class that can
* deliver events synchronously or asynchronously. * deliver events synchronously or asynchronously.
* *
* @param isAsync When true, deliver events asynchronously. * @param [isAsync=false] When true, deliver events asynchronously.
* *
*/ */
constructor(isAsync: boolean = false) { new(isAsync?: boolean): EventEmitter<T>;
super();
this.__isAsync = isAsync;
}
/** /**
* Emits an event containing a given value. * Emits an event containing a given value.
* @param value The value to emit. * @param value The value to emit.
*/ */
emit(value?: T) { emit(value?: T): void;
super.next(value);
}
/** /**
* Registers handlers for events emitted by this instance. * Registers handlers for events emitted by this instance.
* @param generatorOrNext When supplied, a custom handler for emitted events. * @param generatorOrNext When supplied, a custom handler for emitted events.
@ -95,6 +89,21 @@ export class EventEmitter<T> extends Subject<T> {
* @param complete When supplied, a custom handler for a completion * @param complete When supplied, a custom handler for a completion
* notification from this emitter. * notification from this emitter.
*/ */
subscribe(generatorOrNext?: any, error?: any, complete?: any): Subscription;
}
class EventEmitter_ extends Subject<any> {
__isAsync: boolean; // tslint:disable-line
constructor(isAsync: boolean = false) {
super();
this.__isAsync = isAsync;
}
emit(value?: any) {
super.next(value);
}
subscribe(generatorOrNext?: any, error?: any, complete?: any): Subscription { subscribe(generatorOrNext?: any, error?: any, complete?: any): Subscription {
let schedulerFn: (t: any) => any; let schedulerFn: (t: any) => any;
let errorFn = (err: any): any => null; let errorFn = (err: any): any => null;
@ -155,3 +164,11 @@ export class EventEmitter<T> extends Subject<T> {
return sink; return sink;
} }
} }
/**
* @publicApi
*/
export const EventEmitter: {
new (isAsync?: boolean): EventEmitter<any>; new<T>(isAsync?: boolean): EventEmitter<T>;
readonly prototype: EventEmitter<any>;
} = EventEmitter_ as any;