TSTL Extensions
Plugin for TSTL which provides various low-level extensions.
🛠 Installation
- Get the latest package from npm:
npm install -D @cheatoid/tstl-extensions # or yarn add -D @cheatoid/tstl-extensions
- Edit your
tsconfig.json
file accordingly to enable the plugin:{ "compilerOptions": { "types": [ + "@typescript-to-lua/language-extensions", + "@cheatoid/tstl-extensions", ] }, "tstl": { "luaPlugins": [ + { "name": "@cheatoid/tstl-extensions/index.js" }, ] } }
✨ Features
Note: This plugin exposes most of low-level functionality via special functions which are prefixed with double-underscore (__
).
continue
support
If your target Lua environment supports continue
statement (such as Garry's Mod Lua)...
Due to specific nature of this feature, you must explicitly opt-in by modifying your tsconfig.json
file by appending the following:
{
"tstl": {
"luaPlugins": [
{
"name": "@cheatoid/tstl-extensions/index.js",
+ "hasContinue": true
}
]
}
}
With this change applied, you can use continue
in your TS code and it will emit a continue
statement in Lua.
goto
& label support
Only usable if your target Lua environment supports goto
and labels (such as Lua 5.2+ or JIT)...
The following table is hopefully self-explanatory:
TypeScript | Lua |
---|---|
__goto("MyLabel") |
goto MyLabel |
__label("MyLabel") |
::MyLabel:: |
Efficient swapping
This allows you to swap two values without a temporary variable:
The following table is hopefully self-explanatory:
TypeScript | Lua |
---|---|
__swap(arr[0], arr[1]) |
arr[1], arr[2] = arr[2], arr[1] |
unsafe_cast
This is useful in-place replacement for as any
casting, because it allows to "find all references" quickly.
For example, instead of writing foo as any as TheFoo
(or <TheFoo><any>foo
), you can instead do unsafe_cast<TheFoo>(foo)
.
next
iterator support
Call __next
using for-of loop, you may optionally want to specify a starting index.
Example usage:
for (const [k, v] of __next(_G)) {
print(k, v);
}
Transpiles to:
for k, v in next, _G do
print(k, v)
end
Aggressive inlining
Function calls have certain performance overhead. This feature allows to inline the body of the given function in-place, which can be beneficial in hot-path for high-performance code. It mostly just works, but consider it as experimental.
Currently there is a drawback in the implementation, the target function must be defined in the same file where you want to inline it.
Simple example:
function InlineExample(name: string) {
print(`Hello, ${name}`);
print("The code to be inlined goes here");
}
const john = "John";
__inline(InlineExample, john);
__inline(InlineExample, "Moon");
Transpiles to:
local john = "John"
do
local name = john
print("Hello, " .. name)
print("The code to be inlined goes here")
end
do
local name = "Moon"
print("Hello, " .. name)
print("The code to be inlined goes here")
end
Top-level return
This feature allows you to bypass TypeScript limitation - ts(1108) error.
You should only consider this as a last resort option (hint: try using export assignment export = ...
), or if you want to bail out from a script.
Simply call __return
, you may optionally pass additional arguments to be returned at call site.
And more...
I am just tired to go over all of them... I hope there is a little bit of something for everyone to enjoy. :P
📜 History
This plugin was initially published at GitHub Gist (here), which is outdated as of now, perhaps you may still find something interesting down in the comments.
👏 Credits
Special thanks to TypeScriptToLua developers and contributors for their awesome project.