ReadableStream.from() method?
Hi, first of all, thanks for your work on these type declarations, they are invaluable for working with web standards APIs.
It seems as if the following is not yet supported in TS 5.3.3 (also fails in Beta and Nightly):
ReadableStream.from(['a', 'b']);
// ^^^^? Property 'from' does not exist on type '{
// new (body?: BodyInit | null | undefined, init?: ResponseInit | undefined): Response;
// prototype: Response;
// error(): Response;
// json(data: any, init?: ResponseInit | undefined): Response;
// redirect(url: string | URL, status?: number | undefined): Response;
// }'.
- Playground: https://www.typescriptlang.org/play?ts=5.3.3#code/PTAEAsBdIBwZwFwgCYFMBuqA2B7GqAnAOgFscAvASyywEMicCBzYVAOwFoBVAZWGRwBjOMADqqAEbAAggAUAksABKqWsloSsqHpAKqSwAGYEcJAPpxItSJUEAoEBGjwkwS3tok4ROPkFEAd3BrAKYGZmAAYgI4DhgTSBxIAE98OxVfHDY4VCJjUwAKAG0AcloSgBpQEokSgF0ASgBuOyA
- WhatWG Streams Spec https://streams.spec.whatwg.org/#rs-prototype
- MDN ReadableStream: from() static method (experimental) https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream/from_static
Maybe a similar PR is needed to update the types to the WebIDL Streams spec like @MattiasBuelens did in 2020 in https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/890?
Or is this not supported yet because only 3 runtimes (Firefox, Deno and Node.js) support this?
I can also re-submit this in https://github.com/microsoft/typescript if that makes more sense.
I think you meant ReadableStream.from() in your example code, rather than Response.from(). 😉
Or is this not supported yet because only 3 runtimes (Firefox, Deno and Node.js) support this?
Correct, this is still missing browser support. At the moment, only 1 browser engine (Firefox's Gecko engine) has implemented ReadableStream.from(). (Node.js and Deno don't count, since they aren't browser engines.)
Usually, I would suggest to add a type definition to your own code for now. Unfortunately, that doesn't work in this case, since you can't override the type of declare var ReadableStream (playground)... 😕
Off topic
For the JavaScript types, we usually do things like:
interface Array { // instance properties and methods } interface ArrayConstructor { // constructors, static properties and methods } declare var Array: ArrayConstructor;That way, users can augment
ArrayConstructorin their own code, and have extra staticArraymethods that way. Unfortunately, we don't do this for any of the DOM types... (Presumably because it'd add a ton of extra types?)
So for now, you have to add an explicit cast wherever you want to use the extra methods... (playground)
type ReadableStreamExt = (typeof ReadableStream) & {
from<R>(asyncIterable: Iterable<R> | AsyncIterable<R>): ReadableStream<R>;
};
// 😬
(ReadableStream as ReadableStreamExt).from(['a', 'b']);
You can also go click the "+1" button on the Chromium issue, so maybe someone will pick it up. 😁
Hello @karlhorky,
This method has not been implemented yet because it isn't widely adopted. At least two browser engines must support it before it can be considered for implementation.
@MattiasBuelens I managed to work around the overriding issue with this code:
/**
* Interface that extends ReadableStream by adding a static `from` method.
*/
interface ReadableStreamEx<T> extends ReadableStream<T> {
new (underlyingSource?: UnderlyingSource<T> | null, strategy?: QueuingStrategy<T>): ReadableStream<T>;
/**
* Creates a ReadableStream from an iterable source.
* @static
* @param {Iterable<T> | AsyncIterable<T>} iterable The iterable source to create the stream from
* @returns {ReadableStream<T>} A ReadableStream instance containing the data from the iterable
*/
from(iterable: Iterable<T> | AsyncIterable<T>): ReadableStream<T>;
}
/**
* The ReadableStream interface of the Streams API represents a readable stream
* of byte data. Here it is extended to include a static `from` method that allows
* creating a stream from an iterable source.
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStream)
*/
declare var ReadableStream: ReadableStreamEx<any>;
/**
* Polyfill for ReadableStream.from which creates a ReadableStream from an iterable source.
*/
if (typeof ReadableStream.from === "undefined") {
Object.defineProperty(ReadableStream, "from", {
value(iterable: Iterable<any>): ReadableStream {
return new ReadableStream({
async start(controller) {
for await (const chunk of iterable) {
controller.enqueue(chunk);
}
controller.close();
}
});
}
});
}