4
votes

I'm testing use of Rxjs 6.3.3 in a Jasmine test in an Angular 7.2 application. I'm attempting to create an Rxjs Observable but I'm encountering errors that I don't understand.

The function signature of the Rxjs Observable constructor is

constructor(subscribe?: (this: Observable<T>, subscriber: Subscriber<T>) => TeardownLogic);

In a Jasmine test I'm trying to instantiate an Observable instance, this requires me to pass a definition of the lambda in the constructor signature. The following syntax:

const obs = new Observable<number>((this: Observable<number>, s: Subscriber<number>): TeardownLogic => {});

...fails with

"error TS2730: An arrow function cannot have a 'this' parameter."

Which I don't understand this because in the constructor's function signature the arrow function definition is declared with a 'this' argument without it being a problem.

This second syntax:

const obs = new Observable((o: Observable<{}>, s: Subscriber<{}>): TeardownLogic => {});

...fails with

"error TS2345: Argument of type '(o: Observable<number>, s: Subscriber<number>) => TeardownLogic' is not assignable to parameter of type '(this: Observable<number>, subscriber: Subscriber<number>) => TeardownLogic'"

Which I find confusing because the two function signatures in the error message seem identical to me.

What does work though is simply omitting the first argument altogether like this:

const obs = new Observable((s: Subscriber<{}>): TeardownLogic => {});

Which confuses me because now the lambda defined here does not look remotely like the one in the constructor signature.

I'm aware of the use of 'this' in a constructor, and a closure and the different meaning of 'this' in an arrow function. But I'm not aware of any special meaning of 'this' when used as an argument in a method signature. I've Googled around and read the documentation on 'this' in the MDN but am still none the wiser.

In the Observable constructor 'this' in the 'subscribe?: (this: Observable, subscriber: Subscriber) => TeardownLogic' appears to have some kind of magical behaviour. Can anyone explain to me what it is and where I might look to find some documentation about it please?

1
Arrow-functions do not have: this, and do not have arguments and can’t be called with new.Joel
How about Observable.create(...)? learnrxjs.io/operators/creation/create.htmlSereja Bogolubov
I know I can create an Observable in a variety of other ways, but I want to understand what is going on here.Neutrino

1 Answers

3
votes

In function definition:

 (this: Observable<T>, subscriber: Subscriber<T>) => TeardownLogic

Here this is a special syntax in Typescript. It specifies the type of the "this" the function expects. So here it just means it should be called by a Observable with the same Type T as the Subscriber.

It comes first in the parameter list. It is a fake parameter, and should invoked without it.

So your code works:

new Observable((s: Subscriber<{}>): TeardownLogic => {});

I think Typescript just got the type {} and give it to the new Observable, since you did not specify the type. So now they are of the same type.

More info can be found Here: