Skip to content

Language Transforms

rbx-tsx transforms JavaScript and TypeScript language constructs into idiomatic Luau.

TypeScriptLuau
const / letlocal
=== / !==== / ~=
&& / || / !and / or / not
a ?? bif a ~= nil then a else b
a?.b?.ctemp-var optional chaining
cond ? a : bif cond then a else b
`hello ${name}``hello {name}` (Luau string interpolation)
for...offor _, v in items do
for...infor k, _ in obj do
Numeric forfor i = 0, n - 1 do
switch/caseif/elseif/else
try/catch/finallypcall
throwerror()
async/awaitPromise-based transform
function* / yieldCoroutine adapter
new Color3() / Color3.new()Color3.new()
typeof xtypeof(x)
delete obj.keyobj.key = nil
DecoratorsWrapper/descriptor calls
Labeled breakFlag variable pattern
&&= / ||= / ??=Logical assignment
DestructuringLocal variable extraction
Spread { ...a, ...b }_merge(a, b)
Classes with extendsMetatables with __index
get x() / set x(v)Function __index / __newindex dispatch
[key]() {} / "name"() {}Computed/string method name → Class[key] = function
tag`a${x}b`tag({ "a", "b" }, x)
LuaTuple<[A, B]> return(A, B) multiple return values
const [a, b] = tupleCall()local a, b = tupleCall()

Unlike roblox-ts, which relies on installed runtime packages, rbx-tsx inlines the polyfills for these constructs directly into the output:

  • async/await compiles to a Promise-based transform.
  • function* / yield compiles to a coroutine adapter.
  • Class and method decorators compile to wrapper/descriptor calls.

See the async-await, flow, and decorators examples for full input/output pairs.