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;
}
export declare class EventEmitter<T> extends Subject<T> {
constructor(isAsync?: boolean);
export declare interface EventEmitter<T> extends Subject<T> {
new (isAsync?: boolean): EventEmitter<T>;
emit(value?: T): void;
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 {
multi?: boolean;
provide: any;

View File

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