sveltejs / svelte

Cybernetically enhanced web apps
https://svelte.dev
MIT License
78.4k stars 4.1k forks source link

Svelte supports rxjs observables but it is not reflected in types #8726

Open olehmisar opened 1 year ago

olehmisar commented 1 year ago

Describe the bug

I cannot use an rxjs.Observable with derived because svelte's Unsubscriber is not typed properly: https://github.com/sveltejs/svelte/blob/3bc791bcba97f0810165c7a2e215563993a0989b/src/runtime/store/index.ts#L6-L7

It should be typed as

export type Unsubscriber = { unsubscribe(): void; } | (() => void);

Reproduction

import { of } from 'rxjs'
const value = of(0);
derived(value, value => value + 2) // type error

Logs

No response

System Info

not relevant

Severity

annoyance

dummdidumm commented 1 year ago

This is an implementation detail for rxjs interop, but I'm not sure we want to expose it publicly. If you have a rxjs observable, why would you want to use it with derived anyway? Can't use you .pipe and the rxjs operators for that?

olehmisar commented 1 year ago

I want to mix svelte stores with rx observables

hackape commented 1 year ago

Your request is legit, however the severity is so over-stated. I can easily fix it with @ts-ignore and move on. Please report severity properly.

samal-rasmussen commented 8 months ago

I've taken to using these two helpers in order to get interop:

export function store_to_observable<T>(store: Writable<T> | Readable<T>): Observable<T> {
    return new Observable<T>((observer) => {
        return store.subscribe((value) => observer.next(value));
    });
}

export function observable_to_store<T>(observable: Observable<T>): Writable<T> {
    const store = writable<T>();
    observable.subscribe((value) => store.set(value));
    return store;
}

But it sound to me like doing this is perfectly safe:

export function observable_to_store<T>(observable: Observable<T>): Writable<T> {
    return observable as any as Writable<T>;
}

Is this correct?