gildor
10/31/2017, 1:59 AM@file:JsModule("firebase-admin")
but not if I manually define require
function and request module.
After some investigations I’ve found a problem and the reason is not my code or library.
firebase-admin written in typescript and way how TS defines classes and way how kotlin use them this is the problem.
I could reproduce it on minimal example:
this is a typescript class:
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
Compiled to JS:
var Greeter = /** @class */ (function () {
function Greeter(message) {
this.greeting = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + this.greeting;
};
return Greeter;
}());
So if you use this code in a straitforward way everything is fine:
var greeter = new Greeter("world");
console.log(greeter.greet()); //Hello, world
But Kotlin in generated JS code caches object instance functions to variable and call them using this variable (I think to reduce generated code size). And this is the problem for code above.
You can reproduce such problem in pure JS:
var greeter = new Greeter("world");
var greet = greeter.greet;
console.log(greet); // [Function] -- so greet is function
console.log(greeter.greet()) // Hello, world -- works fine
console.log(greet()); // Hello, undefined -- undefined
So instead of reference to instance function we cached prototype function.
Actually it means that Kotlin JS not compatible with TypeScript and some other pre-ES6 class implementations.
Maybe I missed something, I do not work with JS for a long time and not familiar with TS.
I can build later some more self containing example and create an issue.konsoletyper
10/31/2017, 7:59 AMkonsoletyper
10/31/2017, 8:02 AMBut Kotlin in generated JS code caches object instance functions to variable and call them using this variableWrong. Kotlin/JS does not do this. Kotlin caches only some top-level declarations (classes, packages, class-level functions)..
gildor
10/31/2017, 8:09 AM//file: admin.kt
@file:JsModule("firebase-admin")
package admin
external fun initializeApp(options: dynamic): dynamic
//file: functions.kt
@file:JsModule("firebase-functions")
package functions
external fun config(): dynamic
//file main.kt
fun main(args: Array<String>) {
//fully qualified name. `admin` can be imported, no difference
admin.initializeApp(functions.config().firebase)
}
konsoletyper
10/31/2017, 8:14 AMkonsoletyper
10/31/2017, 8:14 AMkonsoletyper
10/31/2017, 8:14 AM@JsModule("firebase-admin")
object FirebaseAdmin {
fun initializeApp(options: dynamic): dynamic
}
gildor
10/31/2017, 8:14 AMexternal val admin: dynamic
gildor
10/31/2017, 8:14 AMgildor
10/31/2017, 8:14 AMgildor
10/31/2017, 8:15 AMkonsoletyper
10/31/2017, 8:15 AMgildor
10/31/2017, 8:16 AMobject FirebaseAdmin
be external object FirebaseAdmin
instead?konsoletyper
10/31/2017, 8:16 AMgildor
10/31/2017, 8:19 AMgildor
10/31/2017, 8:23 AMgildor
10/31/2017, 8:25 AMexternal object
declaration as example in docs - https://kotlinlang.org/docs/reference/js-modules.htmlgildor
10/31/2017, 8:28 AMexternal object
instead of package