Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing properties on *StreamLike types in TypeScript #23

Open
dumbmatter opened this issue Oct 19, 2021 · 4 comments
Open

Missing properties on *StreamLike types in TypeScript #23

dumbmatter opened this issue Oct 19, 2021 · 4 comments

Comments

@dumbmatter
Copy link

First of all, much love for your work here and on the polyfill!

When using this library with TypeScript, if I do something like:

toPolyfillReadable(stream).pipeThrough

it says:

Property 'pipeThrough' does not exist on type 'ReadableStreamLike<any>'

Maybe the properties from https://github.com/microsoft/TypeScript/blob/fd6552a3c2fdfe92afd88ccf6616ec02946e7d9e/lib/lib.dom.d.ts#L11917-L11925 should be copied to

export interface ReadableStreamLike<R = any> {
readonly locked: boolean;
getReader(): ReadableStreamDefaultReader<R>;
}
?

@MattiasBuelens
Copy link
Owner

The ReadableStreamLike type is intended to be the minimum required interface that a stream implementation must support in order to adapt it to a different implementation. So it should really be an input type, but it looks like it also acts as an output type. Hmm... 🤔

Thanks for reporting. I'll see if I can improve the types. 🙂

@MattiasBuelens
Copy link
Owner

Hmm, this might be impossible. 😕

createReadableStreamWrapper needs to take a constructor that returns a generic ReadableStream<R>, and returns a ReadableStreamWrapper which should also return a generic ReadableStream<R>. We don't want to restrict the type of R, because we want this to work:

const toPolyfillReadable = createReadableStreamWrapper(PolyfillReadableStream);
const readable1: PolyfillReadableStream<string> = toPolyfillReadable(new ReadableStream<string>());
const readable2: PolyfillReadableStream<Uint8Array> = toPolyfillReadable(new ReadableStream<Uint8Array>());

To correctly express this, we'd need some sort of "higher kinded types", which doesn't exist yet in TypeScript:

// pseudo code, not real TypeScript
export interface ReadableStreamLikeConstructor<RS extends ReadableStreamLike<?>> {
                                                                         // ~~~ not possible
  new<R = any>(
    underlyingSource?: UnderlyingSource<R>,
    strategy?: QueuingStrategy<R>
  ): RS<R>;
  // ~~~~~  not possible
}

export type ReadableStreamWrapper<RS extends ReadableStreamLike<?>> 
  = <R>(readable: ReadableStreamLike<R>) => RS<R>;

export function createReadableStreamWrapper<RS extends ReadableStreamLike<?>>(
  ctor: ReadableStreamLikeConstructor<RS>
): ReadableStreamWrapper<RS> { /* ... */ }

For the time being, you'll need to manually cast the return value to the desired type yourself:

const toPolyfillReadable = createReadableStreamWrapper(PolyfillReadableStream);
const readable1 = toPolyfillReadable(new ReadableStream<string>()) as PolyfillReadableStream<string>;
const readable2 = toPolyfillReadable(new ReadableStream<Uint8Array>()) as PolyfillReadableStream<Uint8Array>;

I wish I had a better answer. 😞

I am trying to make web-streams-polyfill itself work better together with native streams, which should ideally remove the need for web-streams-adapter entirely. If you're interested, you can follow along in MattiasBuelens/web-streams-polyfill#20.

@dumbmatter
Copy link
Author

Sorry to abuse the issue tracker this way, but do you have a Paypal or BuyMeACoffee or something where I can thank you for your work? It's just really great stuff.

@MattiasBuelens
Copy link
Owner

Thanks for the kind words! 😊

I'm fortunate enough to have a great day job, so I'd feel bad to accept donations. But if you want, you can sponsor other projects and developers, or donate to a charity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants