cincheo / jsweet

A Java to JavaScript transpiler.
http://www.jsweet.org
Other
1.46k stars 160 forks source link

Using addTypeMapping() correctly; "extends" (typed and untyped) #529

Closed jmstark closed 5 years ago

jmstark commented 5 years ago

Hi,

I do not quite understand how one is supposed to correctly use PrinterAdapter::addTypeMapping(). How do I specify the target TS-class correctly? We are using jsweet to transpile a huge (existing) Java project to Typescript. To exclude / cut off innecessary Java classes from transpilation, we map them to a dummy typescript class. Example: addTypeMapping("com.corp.persistence.common.lazy.LazyJoinList", "Object");. This translates this Java class

public class Example<IdType> extends LazyJoinList<IdType> {
...
}

to this TS-Code:

export class Example<IdType> extends Object {
...
}

This does what it should, except that extending Object leads to instances of the class not being able to call methods due to this: https://github.com/microsoft/TypeScript/wiki/FAQ#why-doesnt-extending-built-ins-like-error-array-and-map-work

So ideally I would just create my own dummy class (either in Java or TS, I don't care: export class DummyClass { }) and use that as mapping target instead of Object, but I don't know how to make the class known to JSweet so it can translate the extends statement correctly. Because when I place e.g. addTypeMapping("com.corp.persistence.common.lazy.LazyJoinList", "DummyClass");, it treats it as if it had a type parameter:

export class Example<IdType> extends DummyClass<IdType> {
...
}

even though it doesn't, which then leads to TS compilation errors (also it doesn't add the necessary header). While using Object doesn't cause that behavior, assumingly because it is a builtin class and jsweet thus knows that it does not have type parameters. So how do I pass the target class correctly to addTypeMapping()? I also tried adding the dummy class in the Java source and passing the fully qualified classname to addTypeMapping(), same result.

Thanks in advance!

EDIT: I just tried writing an adapter that defines the TS class, still does not work (except that now at least the header gets imported).

jmstark commented 5 years ago

I still do not know the answer to this question, but I could implement an easy workaround: Write an adapter that defines a dummy TS class with some dummy type parameters which have default values: export class DummyClass<A1 = {}, A2 = {}> {} Then map unused classes to that dummy class.