JavaScript -> Luau

Equivalent JavaScript functions/libraries in the Airship Luau ecosystem.

About

Airship uses the Luau Runtime to run scripts from the cloud. This means all TypeScript files are compiled to Luau instead of JavaScript and there are a few gotcha's when expecting a JavaScript function or library to exist. This page should help cover the conversion from JavaScript expectations to Luau.

Console Logging

  • console.log -> print

  • console.warn -> warn

  • console.error -> error

print("Hello world");
print("anything", "can be", "listed", 10, true, false);

warn("This is a warning");

error("This is an error");
print("This won't print because the above error halted execution");

Unlike in JavaScript, calling error will halt execution of the current Luau thread.

Strings

The Luau string library is available for use. A few extra functions have been added to the string library to help it reach more equivalency to JavaScript:

  • string.trim(str)

  • string.trimStart(str)

  • string.trimEnd(str)

More string utils can be found in the StringUtils global.

Math

Instead of the JavaScript Math library, the Luau math library is available.

ToString

Use the global tostring() function to convert any value to a string.

  • obj.toString() -> tostring(obj)

ParseInt and ParseFloat

In Luau, all numbers are treated as double floats. As such, there is only one equivalent function to parse values into numbers: tonumber().

  • parseInt(value) -> tonumber(value)

  • parseFloat(value) -> tonumber(value)

If the value cannot be converted to a number, nil is returned instead (which we can check as undefined in TypeScript).

Null

The null value is not used in unity-ts. Instead, use undefined. In Luau, this is equivalent to nil.

Throw

Throwing an exception is equivalent to calling the error function. Both compile down to the same Luau code.

Iterating custom objects and enums (Object.entries)

Arrays, Maps and Sets will work as expected and are handled by the compiler. Custom objects and enums however work differently.

In Luau, if we want to iterate over the keys/values of objects (e.g. get all the values of an enum) - we use the pairs function. Think of this like the Luau equivalent of Object.entries.

for..in loops

for..in loops are not supported, you should refer to the above documentation for how to grab keys from objects

Timeouts and Intervals

Luau's coroutine system is much different than the event loop found in JavaScript. The task library contains helpful functions for scheduling and spawning new Luau coroutine threads.

SetTimeout

Use task.delay to schedule a new thread to run in the future.

Using task.wait will also cause a delay; however, it will yield the current thread for the number of seconds, rather than scheduling a new thread for the future.

SetInterval

There is no direct equivalent function to setInterval, but the behavior can be easily reproduced in a few different ways:

Clearing Timeouts and Intervals

Use task.cancel to stop a scheduled or already-running coroutine thread. All thread scheduling functions (task.spawn/defer/delay) return a "thread" object, which can be fed into the cancel function.

JSON

  • JSON.parse -> json.decode

  • JSON.stringify -> json.encode

Since JSON objects are inherently unknown in shape, json.decode will return an unknown type. If desired, a generic type can be used on the decode function, but note that this does not enforce the type.

Empty Objects and Arrays

In Luau, the table type is used for both objects and arrays. While unity-ts lets you specify between various data structures (objects, arrays, maps, sets), they call compile down into Luau tables.

As such, json.encode cannot differentiate between an empty object and an empty array. Any empty structure will be encoded as an empty JSON array: [].

Signed Bitwise operations

In short, bitwise operations will be equivalent to JavaScript's. However, this is different than what would usually be expected from Luau.

By default, any TypeScript bitwise operations go through the sbit32 library. Luau ships with an unsigned bit32 library, but signed bitwise operations mesh better within Unity, as C#'s bitwise operations are also signed.

In general terms, this means that bitwise operations should be expected to be equivalent to what you would already expect from JavaScript. However, if you are coming from a Luau background, please note the difference here.

The bit32 and sbit32 libraries can also be directly used if desired.

Passing a method to a function

In Luau, methods are handled quite differently to JavaScript. When you call a method, the calling object is passed as the first parameter implicitly (through object:Method(...)) or explicitly through object.Method(object, ...).

In unity-ts, if you try passing a method directly as an argument (e.g. doThingWithAMethod(object.Method)) you will end up with "Cannot index method without calling it!"

The best way to deal with this, is to explicitly "bind" a function to object

This will ensure that Luau will call it as a method attached to object when you call the bound function

Other

All Luau libraries are available for use.

Last updated