You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
TS allows adding Uint8Array item to Array<ArrayBuffer> #31311
interfaceSimpleReadStream{onData: (data: ArrayBuffer)=>any;}declarefunctioncreateFileReadStream(name: string): SimpleReadStream;// CASE 1conststream1: SimpleReadStream=createFileReadStream(name);constblobData1: ArrayBuffer[]=[];stream1.onData=data=>{// TYPE MISMATCH (but no error)blobData1.push(newUint8Array(data));};// CASE 2conststream2: SimpleReadStream=createFileReadStream(name);constblobData2: Uint8Array[]=[];stream2.onData=data=>{// TYPE MISMATCH (error as expected)blobData2.push(data);};
Sure, Array.prototype.push has covariant inputs, and an instance of Uint8Array has all of the properties that an instance of ArrayBuffer has, so typescript's structural typing considers Uint8Array extends ArrayBuffer to be true.
(Leaving off toStringTag here as not all editions have it, but it doesn't fundamentally change the example.)
Any object that has these methods and properties is compatible with an ArrayBuffer. It doesn't matter if there's some behavioral difference between them, because TypeScript does not measure those things and TypeScript does not use nominal typing.
In the example I posted, I give an object which is obviously not an ArrayBuffer - byteLength is always 42, slice returns the same object again regardless of parameters. But it passes because all Typescript cares is:
Does this object have a byteLength property of type number?
Does this object have a slice() method, optionally taking 0-2 number parameters, that returns an object that also satisfies 1 and 2?
You keep explkainig what TS does. I already know what TS does. And it's wrong, because ArrayBuffer != Uint8Array. I already know TS thinks otherwise — if it was different I would not have to open this issue. I *cannot use an array of mixed ArrayBuffer and Uint8Array, e.g. to concatenate them — because they are not the same and it would not work (during runtime).
Activity
nmain commentedon May 8, 2019
Sure,
Array.prototype.pushhas covariant inputs, and an instance ofUint8Arrayhas all of the properties that an instance ofArrayBufferhas, so typescript's structural typing considersUint8Array extends ArrayBufferto be true.lll000111 commentedon May 8, 2019
Nicholai Main (@nmain) But a Uint8Array is not an ArrayBuffer, two very different objects. You can't mix them.
nmain commentedon May 8, 2019
Read up on structural typing https://www.typescriptlang.org/docs/handbook/type-compatibility.html, and then wrap your head around this example:
http://www.typescriptlang.org/play/#src=const%20Nmain_SuperArray%20%3D%20%7B%0D%0A%20%20%20%20byteLength%3A%2042%2C%0D%0A%20%20%20%20slice()%20%7B%0D%0A%20%20%20%20%20%20%20%20return%20Nmain_SuperArray%0D%0A%20%20%20%20%7D%2C%0D%0A%20%20%20%20%5BSymbol.toStringTag%5D%3A%20%22Awesome!%22%0D%0A%7D%0D%0A%0D%0A%2F%2F%20passes%20typecheck%0D%0Aconst%20s%3A%20ArrayBuffer%20%3D%20Nmain_SuperArray%0D%0A
In short, all it matters is that
Uint8ArrayhasbyteLengthandslice()that work similarly toArrayBuffer, and it does.lll000111 commentedon May 8, 2019
I don't need to, I know what it is. Read my comment #31311 (comment)
nmain commentedon May 8, 2019
I'm sorry my example wasn't clear enough for you. Let me show you the exact definition for
ArrayBufferinside Typescript:(Leaving off
toStringTaghere as not all editions have it, but it doesn't fundamentally change the example.)Any object that has these methods and properties is compatible with an ArrayBuffer. It doesn't matter if there's some behavioral difference between them, because TypeScript does not measure those things and TypeScript does not use nominal typing.
In the example I posted, I give an object which is obviously not an ArrayBuffer -
byteLengthis always 42,slicereturns the same object again regardless of parameters. But it passes because all Typescript cares is:byteLengthproperty of typenumber?slice()method, optionally taking 0-2numberparameters, that returns an object that also satisfies 1 and 2?lll000111 commentedon May 8, 2019
Nicholai Main (@nmain)
???
Infinite loop detected. I already answered.
#31311 (comment)
#31311 (comment)
You keep explkainig what TS does. I already know what TS does. And it's wrong, because ArrayBuffer != Uint8Array. I already know TS thinks otherwise — if it was different I would not have to open this issue. I *cannot use an array of mixed ArrayBuffer and Uint8Array, e.g. to concatenate them — because they are not the same and it would not work (during runtime).
nmain commentedon May 8, 2019
I am sorry that I misread you. Your terse comments did not give me much to work with to understand your intent.
This is a duplicate of #202 and there have been other discussions of it as well.
#10882
#5855
etc
weswigham commentedon May 8, 2019
FYI, in your own project, you can make the various
Buffertypes distinguishable by augmenting them with type-specific tags, eg:we briefly trialed using
Symbol.toStringTagin this way, but making the buffers distinguishable actually breaks a number of people, apparently.typescript-bot commentedon May 11, 2019
This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.