byte[] does not work as type parameter when return value is Uint8array
rbsdc opened this issue · 2 comments
Describe the bug
When byte[] is used as type parameter and an Uint8Array is used as return value in JavaScript, then an error is thrown. If byte[] is used directly, it works fine with Uint8Array. Mentioned in a comment here: #144.
To Reproduce
The following code does work when transpiled to JavaScript:
interface FileReader {
byte[] readRange(int offset, int length);
}
class FileTest {
public void doSomething(FileReader reader) {
byte[] bytes = reader.readRange(0, 10);
}
}
In Javascript:
class FileReader {
readRange(offset, length) {
return new Uint8Array([1, 2]);
}
let fileTest = new FileTest();
fileTest.doSomething(new FileReader()) // works
}
The following does not work:
@JsType
public interface Thenable {
@JsFunction
interface FullFilledCallback {
void execute(byte[] o);
}
@JsFunction
interface RejectedCallback<T> {
void execute(byte[] o);
}
void then(FullFilledCallback onFulfilled, RejectedCallback onRejected);
}
interface FileReader {
Thenable<byte[]> readRange(int offset, int length);
}
class FileTest {
public void doSomething(FileReader reader) {
reader.readRange(0, 10).then(bytes ->
//do something with the bytes
);
}
}
In Javascript:
class FileReader {
readRange(offset, length) {
return new Promise((resolve, reject) => {
resolve(new Uint8Array([1, 2]));
});
}
let fileTest = new FileTest();
fileTest.doSomething(new FileReader()) // throws something similar to Error: Class$obf_1003: Class$obf_1001 cannot be cast to [LClass$obf_1002]...
}
Bazel version
5.1.0
This is because byte[]
is not a Uint8Array
but it is a Array<number>
with extra metadata. We are considering mapping primitive arrays to TypedArray but that's not going to be soon.
If you really would like to use byte[]
in JS, one option you have is to create a static function that returns a byte[]
.
Either the function can take byte parameters and return constructed array:
static byte[] createByteArray(byte... bytes){ return bytes;}
or you can manipulate returned empty array to add items.
If you care about using Uint8Array
from Java side, then you can use Elemental2 or JsArrayLike
from the jsinterop.base library.
Thank you for the clarification. I already thought that Uint8Array
might not be the correct byte[]
equivalent, but wondered anyhow why it did work when using a plain byte[]
parameter (as described above and in the other issue). Anyway, by using your suggested method static byte[] createByteArray(byte... bytes){ return bytes;}
and manipulating the returned array I made it work. Thank you again!