From 704191d3c91f25463ef5732cb61a8d779572683b Mon Sep 17 00:00:00 2001 From: Mattias Buelens Date: Fri, 29 Oct 2021 23:10:25 +0200 Subject: [PATCH] Use brand check of .locked in IsReadableStreamLike --- src/lib/helpers/stream-like.ts | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/lib/helpers/stream-like.ts b/src/lib/helpers/stream-like.ts index 071240e..28f36e4 100644 --- a/src/lib/helpers/stream-like.ts +++ b/src/lib/helpers/stream-like.ts @@ -63,13 +63,23 @@ interface WritableStreamDefaultWriterLike { } export function IsReadableStreamLike(x: unknown): x is ReadableStreamLike { - return typeIsObject(x) && typeof (x as ReadableStreamLike).getReader === 'function'; -} - -export function IsReadableByteStreamLike(x: unknown): x is ReadableByteStreamLike { - if (!IsReadableStreamLike(x)) { + if (!typeIsObject(x)) { return false; } + if (typeof (x as ReadableStreamLike).getReader !== 'function') { + return false; + } + try { + // noinspection SuspiciousTypeOfGuard + return typeof (x as ReadableStreamLike).locked === 'boolean'; + } catch { + // ReadableStream.prototype.locked may throw if its brand check fails + return false; + } +} + +export function IsReadableByteStreamLike(x: ReadableStreamLike): x is ReadableByteStreamLike { + assert(IsReadableStreamLike(x)); // This brand check only works for unlocked streams. // If the stream is locked, getReader() will throw even if "byob" is actually supported. @@ -85,5 +95,17 @@ export function IsReadableByteStreamLike(x: unknown): x is ReadableByteStreamLik } export function IsWritableStreamLike(x: unknown): x is WritableStreamLike { - return typeIsObject(x) && typeof (x as WritableStreamLike).getWriter === 'function'; + if (!typeIsObject(x)) { + return false; + } + if (typeof (x as WritableStreamLike).getWriter !== 'function') { + return false; + } + try { + // noinspection SuspiciousTypeOfGuard + return typeof (x as WritableStreamLike).locked === 'boolean'; + } catch { + // WritableStream.prototype.locked may throw if its brand check fails + return false; + } }