Open pintomau opened 3 years ago
Hi @pintomau thanks for feedbak
Really this project is most related to generate Typescript compatible declarations for Java Object useful to make easier interoperability with Java if you'd like use Typescript to develop on top of GraalJS
Your suggestion is mostly for the GraalJS runtime and I'll take it in consideration in the examples
Just want to add an example to this.
This flag makes it more natural to work with Java objects from the PoV of someone coming from the JS/TS world.
Instead of working with stream().map()
or .get(0)
, you'd simply use .map()
and [0]
.
Currently solved this in our code like this:
/**
* This type represents the union of Java's List and Javascript's Array types.
*
* It's useful because we're using the js.foreign-object-prototype GraalJS option which
* wraps the List type with a compatible Array API.
*
* @template E the concrete type hold by the list
*/
type JavaListProxy<E> = List<E> & [E]
// @ts-expect-error Java Lists are wrapped with a JS Array compatible type, therefore we're using an intersection type
const technicalEquipments: JavaListProxy<TechEquipmentItem> = vehicleItem.getTechnicalEquipments() ?? []
const techEquipment = technicalEquipments.find(...)
And by the way. Thanks a lot for the work you did here. Saved me a looot of time.
Actually found a better way, it seems.
Create an overrides.d.ts
file, add your own interface List<E> extends Array<E>
(sort
conflicts, I simply removed it, but ymmv), and add it last in the .tsconfig
includes list.
Hi @pintomau could you provide me a more complete example of that so I could integrate it inside processor ?
Hi @bsorrentino , if you mean the overrides logic, then it looks like this:
declare namespace java.util {
/**
* List<E> overwrite that takes into account GraalJS' foreign-object-prototype where Lists are enriched with Javascript methods.
*
* Please note that due to conflicts, we're delegating sort, forEach, indexOf, lastIndexOf to JS' Array
*/
interface List<E> extends Array<E>/* extends Collection<E> */ {
// static copyOf<E>( arg0:Collection<E> ):List<E>;
// static of<E>( ):List<E>;
// static of<E>( ...arg0:E[] ):List<E>;
// static of<E>( arg0:E ):List<E>;
// static of<E>( arg0:E, arg1:E ):List<E>;
// static of<E>( arg0:E, arg1:E, arg2:E ):List<E>;
// static of<E>( arg0:E, arg1:E, arg2:E, arg3:E ):List<E>;
// static of<E>( arg0:E, arg1:E, arg2:E, arg3:E, arg4:E ):List<E>;
// static of<E>( arg0:E, arg1:E, arg2:E, arg3:E, arg4:E, arg5:E ):List<E>;
// static of<E>( arg0:E, arg1:E, arg2:E, arg3:E, arg4:E, arg5:E, arg6:E ):List<E>;
// static of<E>( arg0:E, arg1:E, arg2:E, arg3:E, arg4:E, arg5:E, arg6:E, arg7:E ):List<E>;
// static of<E>( arg0:E, arg1:E, arg2:E, arg3:E, arg4:E, arg5:E, arg6:E, arg7:E, arg8:E ):List<E>;
// static of<E>( arg0:E, arg1:E, arg2:E, arg3:E, arg4:E, arg5:E, arg6:E, arg7:E, arg8:E, arg9:E ):List<E>;
add(arg0: E): boolean
add(arg0: int, arg1: E): void
addAll(arg0: Collection<E>): boolean
addAll(arg0: int, arg1: Collection<E>): boolean
clear(): void
contains(arg0: any /* java.lang.Object */): boolean
containsAll(arg0: Collection<any /* java.lang.Object */>): boolean
equals(arg0: any /* java.lang.Object */): boolean
// forEach<T>(arg0: Consumer<T>): void
forEach(callbackfn: (value: E, index: number, array: E[]) => void, thisArg?: any): void;
get(arg0: int): E
// indexOf(arg0: any /* java.lang.Object */): int
indexOf(searchElement: E, fromIndex?: number): number;
isEmpty(): boolean
iterator(): Iterator<E>
// lastIndexOf(arg0: any /* java.lang.Object */): int
lastIndexOf(searchElement: E, fromIndex?: number): number;
listIterator(): any /* java.util.ListIterator */
listIterator(arg0: int): any /* java.util.ListIterator */
parallelStream(): java.util.stream.Stream<E>
remove(arg0: any /* java.lang.Object */): boolean
remove(arg0: int): E
removeAll(arg0: Collection<any /* java.lang.Object */>): boolean
removeIf(arg0: Predicate<E>): boolean
replaceAll(arg0: UnaryOperator<E>): void
retainAll(arg0: Collection<any /* java.lang.Object */>): boolean
set(arg0: int, arg1: E): E
size(): int
// sort(arg0: any /* java.util.Comparator */): void
sort(compareFn?: (a: E, b: E) => number): this;
spliterator(): any /* java.util.Spliterator */
stream(): java.util.stream.Stream<E>
subList(arg0: int, arg1: int): List<E>
toArray(): [any /* java.lang.Object */]
toArray<T>(arg0: [T]): [T]
toArray<T>(arg0: any /* java.util.function.IntFunction */): [T]
} // end List
}
Notice that I had to comment some of Java's forEach, indexOf, lastIndexOf and sort methods because of clashing signatures with JS's Array.
And actually, override might not be the ideal name here. This does actually not replace the List type, but this works through Typescript's namespace merging, which I was not familiar with when I wrote the last comment. So, it's not the perfect solution.
Hi @pintomau
I've deployed dev release 1.4-SNAPSHOT
with fix.
please take a chance to test it an let me know
Thanks in advance
Something's weird.
It's not correctly closing classes/interfaces/namespaces:
installed localy from 9d1bfba4c41a272e410a7db908721c47d1927709
Hi @pintomau
I've update dev release 1.4-SNAPSHOT
with fix.
please take a chance to test it an let me know
Take note that to enable foreign-object-prototype
yo have add the following processor options
<options>
<ts.outfile>jdk8</ts.outfile>
<compatibility>GRAALJS</compatibility>
<foreignobjectprototype>true</foreignobjectprototype>
</options>
Thanks in advance.
Yup, now everything is looking good.
As explained in the documentation https://www.graalvm.org/reference-manual/js/Options/#to-the-launcher
So, for example, List could extend Array and so on.