JavaScript First Steps
After about a month, I’ve started coding again. As part of what I’m working on, I’m finally trying to actually learn JavaScript.
While I have some familiarity, most of what I know is years old—I’ve rarely written JavaScript over the years, and the little I wrote involved vanilla JS and jQuery. While I’ve done a tiny bit of learning in the past (basically, I conceptually understand React), I really don’t know that much.
So, basically, I have a lot to learn. This post is going to be more of a log of those learnings.
TypeScript
Because of a library I want to use, I need to learn TypeScript. This is a good thing—I’ve only heard good things about it, and it’s been something I’ve wanted to start learning about it for a while.
The first step to learning about TypeScript is reading the TypeScript Handbook.
The syntax and many of the features seemed intuitive. I’ve (tried to) learn a few different languages at this point, so it’s a lot easier to spot and understand the ideas in the language.
As the name sounds, one of the most powerful things about TypeScript is its typing. Thinking of types as sets is somewhat comfortable to me—between math knowledge, Java interfaces, and learning Rust, the concept is reasonable enough to understand.
What I found interesting is how “freely” the typing works. It’s cool how you don’t need to declare an object’s type—the type is just checked against the expected shape. Coming from Java, this is simultaneously cool and very bizarre.
Literal types are also pretty interesting. Again, it’s both cool and terrifying that I can say a type is a union of certain string values.
Kotlin/JS
Now, while I read up on TypeScript, I’m not actually writing it. Instead, I’m aiming to use Kotlin/JS.
If you’re not familiar with Kotlin, their ambition is pretty neat: they want to be a single language that can be used for various platforms—web, Android, iOS, etc.
When it comes to JavaScript, this done though Kotlin/JS and involves interop. The idea is that you can write type-safe Kotlin code, and it’s turned into JS that runs as if it was written natively.
Challenges & Learnings
The major problem I’ve been grappling with is getting the JavaScript and Kotlin interop working. Essentially, while Kotlin has interop, you need to explicitly teach it about the JavaScript types that you’re using.
Syntax
Almost all of the relevant syntax is here.
A few takeaways:
js()
takes a string constant and lets you inline arbitrary JavaScript.- The
external
keyword lets you specify that a [class / function / variable] is defined externally—in the JavaScript you’re trying to use. You use this to specify the type signature. - Quite often, I found myself using external on interfaces:
external interface Foo {...}
. - When importing, you may need to tell Kotlin where to find a module via
@file:JsModule
.
Generating External Declarations
Generating these external declarations is annoying. It’s a bunch of overhead work for any library you want to use.
The Kotlin team is aiming to improve this with Dukat, which is still experimental. It generates declarations based on .d.ts
(TypeScript declaration) files.
Unfortunately, this didn’t work for me. I’m not sure what’s not working, but I think it’s related to a transitive dependency.
If Dukat doesn’t work, the alternative is to write things by hand. You can save some time by reusing the declarations generated by Dukat, as described here.
This post touches on these Dukat-generated declarations; it was helpful for understanding more of what’s going on. He recommends just taking what you need from the generated files. I agree with this—to avoid getting bogged down, my current approach is to add declarations as I need them.
Object Expressions
In Kotlin, you can create anonymous objects via object expressions.
This is useful because, at some point, you’ll need to create the equivalent of object literals that have some type from an external dependency. These dependencies are often declared as external interface
, so you don’t have a way to construct them. (I initially made the mistake of trying to define implementing classes…this got messy.)
The object expression recommendation comes from here. The example there makes sense but it didn’t seem to quite work for me (I think due to my specific dependencies). It looks like this:
val headers: dynamic = object{}
headers["User-Agent"] = "request"
val options: dynamic = object{}
options["url"] = "http://api.gdax.com/products/BTC-USD/ticker"
options["json"] = true
options["headers"] = headers
Fortunately, I discovered JS kotlin-extensions. In particular, they define a js
function that lets you write the above example like this:
val options =
js {
url = "http://api.gdax.com/products/BTC-USD/ticker"
json = true
headers = headers
}