从Java接口生成TypeScript接口

40

我有一个Java服务器应用程序,它使用Jackson和反射API通用地序列化数据传输对象(DTO)。例如对于此DTO接口:

package com.acme.library;
public interface Book { 
  com.acme.library.Author getAuthor();
  String getTitle();
}

通过该接口的POJO实现,Jackson将泛化序列化以下实体:

{
   "author": { "name": "F. Scott Fitzgerald"},
   "title": "The Great Gatsby"
}

从我基于AngularJS的TypeScript应用程序中,将使用HTTP GET接收此有效载荷:

$http.get("http://localhost/books/0743273567")
   .success((book: Book) => { ... });

为了能够利用 TypeScript 的强类型特性,我发现自己需要手动编写以下 TypeScript 接口:

module com.acme.library {
  export interface Book {
      author: com.acme.library.Author;
      title: String;
  }
}
作为结果,我不得不维护两份相同界面的副本--这最多是繁琐的。 这尤其令人讨厌,因为我想在两个界面上都有相同的javadoc/jsdoc注释,这需要大量的复制和粘贴。

我想找到一种自动化这个过程的机制。

Java是我的主要开发语言。 因此,我想找到一些工具,它能够通过反射API从Java接口声明转换为相关的TypeScript接口。

我在这个领域发现的唯一工具是NPM包ts-java。 但是,这对我的使用情况来说过于笨重了。 它会将Object层次结构中的方法添加到每个接口中,例如hashCode()wait()getClass()等。


1
我目前也在寻找这个。你找到了有趣的东西吗? - iberbeu
3
@iberbeu -- 很抱歉,我不能。 - jwa
5个回答

33

正如larslonne所提到的,您可以使用typescript-generator。它可以从Java JSON类生成TypeScript接口。一些您可能会发现有用的功能包括:

  • Maven和Gradle插件(也可以直接从Java调用)
  • Jackson 1和Jackson 2
  • 集合、枚举、继承、泛型
  • Javadoc注释转换为JSDoc注释
  • 详细文档(README、Wiki、Maven插件)
  • 发布到Maven中央仓库

这是一个使用Maven的示例:

<plugin>
    <groupId>cz.habarta.typescript-generator</groupId>
    <artifactId>typescript-generator-maven-plugin</artifactId>
    <version>1.25.322</version>
    <executions>
        <execution>
            <id>generate</id>
            <goals>
                <goal>generate</goal>
            </goals>
            <phase>process-classes</phase>
            <configuration>
                <jsonLibrary>jackson2</jsonLibrary>
                <classes>
                    <class>com.acme.library.Book</class>
                </classes>
                <outputFile>target/rest.d.ts</outputFile>
                <outputKind>module</outputKind>
            </configuration>
        </execution>
    </executions>
</plugin>

编辑:使用mvn process-classes或稍后的阶段,如mvn install来运行它。
您还可以将<configuration>元素上移两个级别,并运行mvn typescript-generator:generate

编辑:我是typescript-generator的作者。


我尝试运行示例项目,但是出现了以下错误:描述资源路径位置类型未找到artifact cz.habarta.typescript-generator:typescript-generator-maven-plugin:jar:1.7-SNAPSHOT pom.xml /test line 1 Maven pom加载问题。 - Dor Cohen
1
当我更新到1.10.220时,我遇到了以下错误: 插件执行未被生命周期配置覆盖:cz.habarta.typescript-generator:typescript-generator-maven-plugin:1.10.220:generate(执行:generate,阶段:process-classes) - Dor Cohen
@DorCohen,看起来这是您的Maven构建配置(pom.xml)出了一些问题。您可以将您的pom.xml文件发送给我吗?您可以在GitHub上提交问题,我会尽力帮助您。 - Vojta
@Vojita,有没有一种方法可以配置构建过程,使得我们转换的每个对象都可以去到自己单独的.d.ts文件中?我在文档中没有看到它(也许是我错过了)。 - Kevin Gleeson
1
@KevinGleeson 不可能,在单次运行中它只会生成一个文件/模块。 - Vojta
显示剩余3条评论

3
我使用了Amdatu TypeScript Generator并取得了很好的运行效果。它可以在Gradle中运行,也可以从终端独立运行(我使用了终端,因此以下说明以此为准)。
只需要克隆该仓库,运行./gradlew进行编译。
要执行它,我不得不与他们的说明有些偏差,因为jar包中没有入口点(如果你使用Gradle构建,则不会出现这个问题,因为它会指定入口类)。
我使用了:
java -cp build/libs/org.amdatu.typescriptgenerator-1.0-SNAPSHOT.jar org.amdatu.typescriptgenerator.standalone.TypeScriptGeneratorStarter

然后它会抱怨说没有 typescript.settings.json 文件,它期望在你运行命令的目录中找到。

我会提供自己的示例,因为链接的存储库示例设置文件有点不清楚:

{
  "folder" : "/projectsfolder/project",
  "classFolder" : "target/classes",
  "output" : "typscriptOutputDirectory",
  "baseFolder" : "",
  "clearOutput" : false,
  "packages" : [
    ".*regexforwhatpackagesinsidetargetprojectshouldbeturnedintotypescript.*"
  ],
  "excludePackages" : [ ],
  "excludePattern" : [ ],
  "types" : { },
  "mapping" : { },
  "enumType" : "class",
  "classType" : "interface",
  "classPath" : [ ]
}

在设置中最重要的字段如下:

  • folder 是你已经构建项目的位置
  • classFolder 是该生成器将在该文件夹内查找已编译的java类的位置
  • output 相对于执行生成器的位置,该目录是放置TypeScript定义文件的目录
  • packages 是Java正则表达式,用于将哪些包转换为TypeScript定义

3
我目前正在一个与你的设置相同的项目上工作:一个Java API和一个TypeScript Web应用程序。
我们使用"cz.habarta.typescript-generator.typescript-generator-maven-plugin"来在构建API时生成".d.ts"文件。然后,使用"org.codehaus.mojo.build-helper-maven-plugin"将这些定义文件打包为一个带有"d.ts"的构件。最后,在Web应用程序中将该构件作为依赖项导入,其中定义文件被解压缩到"target"目录中。
这个设置要求您在Web应用程序中使用Maven,这并不理想,但为了自动生成定义文件,这是一个小代价。

1
我创建了一个新项目,旨在尽可能简化转换过程:JavaModel-Converter 它可以在IDE中工作,也可以通过执行位于dist文件夹中的jar来执行命令行。
你只需要将你的Java模型放入所需的文件夹中,并开始转换过程即可。
我还添加了对Angular样式的支持。
如果您有请求,请打开问题!
理论上,我的项目是一个通用的Java模型转换器,但实际上,只支持TypeScript转换。

0

你可以使用Script4J,这是一个库集合,可以使用Java API编写TypeScript代码。虽然这是一个新项目,但它可能会很有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接