node.jsrxjsrxjs-observables

RxJS error: TypeError: finalizer.unsubscribe is not a function


This sample code throws an error when running on rxjs 7.8.1:

import { Observable } from 'rxjs';

new Observable((sub) => {
    return setTimeout(() => {
        sub.next("Test");
        sub.complete();
    }, 1000);
}).subscribe({
    next(value) {
        console.log(value);
    }
});

Output:

    TypeError: finalizer.unsubscribe is not a function
        at execFinalizer (/home/jsturm/Alfred/template-service/node_modules/rxjs/dist/cjs/internal/Subscription.js:175:19)
        at Subscription.unsubscribe (/home/jsturm/Alfred/template-service/node_modules/rxjs/dist/cjs/internal/Subscription.js:89:29)
        at Subscriber.unsubscribe (/home/jsturm/Alfred/template-service/node_modules/rxjs/dist/cjs/internal/Subscriber.js:75:42)
        at Subscriber._complete (/home/jsturm/Alfred/template-service/node_modules/rxjs/dist/cjs/internal/Subscriber.js:95:18)
        at Subscriber.complete (/home/jsturm/Alfred/template-service/node_modules/rxjs/dist/cjs/internal/Subscriber.js:69:18)
        at Timeout._onTimeout (file:///home/jsturm/Alfred/template-service/test/observable.js:7:13)
        at listOnTimeout (node:internal/timers:569:17)
        at process.processTimers (node:internal/timers:512:7)

However if I remove the return statement it runs as expected. And when running on RxJS 6.x the error did not appear.

It's a simple fix, but can anyone explain why it was wrong?

I expected an error message that would help us to diagnose the issue.


Solution

  • Have a look at the constructor signature :

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

    With

    export declare type TeardownLogic = Subscription | Unsubscribable | (() => void) | void;
    

    setTimeout returns an id and not a one of the types above.

    You whould have been warned if you used typescript.