🐥
Kotlin/JSでTypeScriptの型定義ファイルを生成する方法
Kotlin1.4からKotlin/JSのKotlinコードからTypeScriptの型定義ファイル(.d.ts)が生成されるようになったみたいなので、少し触ってみました。
この機能はIRコンパイラ専用の機能で、まだプレビュー版なので業務に使うにはまだ早そうです。
型定義ファイルを生成機能を使う準備
build.gradle.ktsでIRコンパイラー使うように設定
- jsの第一引数にIRを指定
-
binaries.executable()
をkotlin内に記述
...
kotlin {
js(IR) { // ①
browser {
}
binaries.executable() // ②
}
}
使い方
@JsExport
を付与
1. 型定義を生成したい物に ※ @JsExport
はトップレベルの物にしかつけれないので注意
@JsExport
class TopLevelClass(val a: Int, var b: Int)
gradle build
を実行
2. build/js/packages/{プロジェクト名}/kotlin/{プロジェクト名}.d.ts
に型定義ファイルが生成されます。
いろいろ試してみた
top level class
Kotlinコード
@JsExport
class TopLevelClass(val a: Int, var b: Int)
.d.ts
export class TopLevelClass {
constructor(a: number, b: number);
readonly a: number;
b: number;
}
extend class
Kotlinコード
@JsExport
open class SuperClass(val superA: Int)
@JsExport
class SubClass(val subA: Int): SuperClass(1)
.d.ts
export class SuperClass {
constructor(superA: number);
readonly superA: number;
}
export class SubClass extends SuperClass {
constructor(subA: number);
readonly subA: number;
}
※ 親クラスにも @JsExport
をつけないと親クラスの型定義は出力されません。
top level data class
Kotlinコード
@JsExport
data class DataClass(val a: Int, var b: Int)
.d.ts
export class DataClass {
constructor(a: number);
readonly a: number;
component1(): number;
copy(a: number): DataClass;
toString(): string;
hashCode(): number;
equals(other: Nullable<any>): boolean;
}
Nested Class
Kotlinコード
@JsExport
class OuterClass(val outerA: Int) {
class NestedClass(val innerA: Int)
}
コンパイルエラー...
e: java.lang.IllegalStateException: Can't find name for declaration CLASS CLASS name:NestedClass modality:FINAL visibility:public superTypes:[kotlin.Any]
Inner Class
Kotlinコード
@JsExport
class OuterClass(val outerA: Int) {
inner class InnerClass(val innerA: Int)
}
コンパイルエラー...
e: java.lang.IllegalStateException: Can't find name for declaration CLASS CLASS name:InnerClass modality:FINAL visibility:public [inner] superTypes:[kotlin.Any]
interface
Kotlinコード
@JsExport
interface Interface {
fun method(a: Int): Int
fun defaultMethod(a: Int): Int = a
val field: Int
}
.d.ts
export interface Interface {
method(a: number): number;
defaultMethod(a: number): number;
readonly field: number;
}
abstruct class
Kotlinコード
@JsExport
abstract class AbstractClass(val a: Int)
.d.ts
export interface Interface {
method(a: number): number;
defaultMethod(a: number): number;
readonly field: number;
}
object
Kotlinコード
@JsExport
object Object {
val a: Int = 1
}
コンパイルエラー...
e: java.lang.IllegalStateException: Class Object with kind: OBJECT
companion object
Kotlinコード
@JsExport
class A {
companion object {
fun method(): Int = 0
val a: Int = 0
}
}
コンパイルエラー...
e: java.lang.IllegalStateException: Class DataClass.Companion with kind: OBJECT
top level function
Kotlinコード
@JsExport
fun topLevelFunction(): Int = 0
export function topLevelFunction(): number;
Enum Class
Kotlinコード
@JsExport
enum class Enum {
A, B, C
}
コンパイルエラー...
@JsExport
はEnumにつけることができない
Declaration of such kind (enum class) cant be exported to JS
バグの状況などはyoutrackで管理されてます
まとめ
まだプレビュー版という事もありバグは多いですが、型定義ファイルが生成できるようになったので、Kotlin/JSでライブラリを作るみたいなパターンは増えてきそうだと思いました。
Discussion