diff --git a/docs/advanced/compiler-annotations.md b/docs/advanced/compiler-annotations.md index c7a63cd7..f2566810 100644 --- a/docs/advanced/compiler-annotations.md +++ b/docs/advanced/compiler-annotations.md @@ -137,30 +137,6 @@ local inst = MyConstructor(3) -## @luaTable - -**Target elements:** `type` - -This annotation signals the transpiler to translate a class as a simple lua table for optimization purposes. - -```ts -/** @luaTable */ -declare class Table { - readonly length: number; - set(key: K, value: V | undefined): void; - get(key: K): V | undefined; -} - -const tbl = new Table(); // local tbl = {} - -const foo = {}; -tbl.set(foo, "bar"); // tbl[foo] = "bar" -print(tbl.get(foo)); // print(tbl[foo]) - -tbl.set(1, "baz"); // tbl[1] = "baz" -print(tbl.length); // print(#tbl) -``` - ## @noResolution **Target elements:** `module` @@ -751,7 +727,7 @@ for i = 10, 1, -1 do end ### @luaIterator - + **Target elements:** `(declare) interface` @@ -834,3 +810,44 @@ for a, b in string.gmatch("foo", "(.)(.)") do end ``` + +### @luaTable + + + +**Target elements:** `type` + +This annotation signals the transpiler to translate a class as a simple lua table for optimization purposes. + +```ts +/** @luaTable */ +declare class Table { + readonly length: number; + set(key: K, value: V | undefined): void; + get(key: K): V | undefined; +} + +const tbl = new Table(); // local tbl = {} + +const foo = {}; +tbl.set(foo, "bar"); // tbl[foo] = "bar" +print(tbl.get(foo)); // print(tbl[foo]) + +tbl.set(1, "baz"); // tbl[1] = "baz" +print(tbl.length); // print(#tbl) +``` + +**Upgrade Instructions** + +Use the built-in [`LuaTable` language extension](language-extensions.md#lua-table-types) instead of a custom annotated type. + +```ts +const tbl = new LuaTable(); // local tbl = {} + +const foo = {}; +tbl.set(foo, "bar"); // tbl[foo] = "bar" +print(tbl.get(foo)); // print(tbl[foo]) + +tbl.set(1, "baz"); // tbl[1] = "baz" +print(tbl.length()); // print(#tbl) +``` diff --git a/docs/advanced/language-extensions.md b/docs/advanced/language-extensions.md index 05610af0..68c084a2 100644 --- a/docs/advanced/language-extensions.md +++ b/docs/advanced/language-extensions.md @@ -223,3 +223,101 @@ const scaled: Vector = Vector.mul(a, 2); - LuaBitwiseNot / LuaBitwiseNotMethod (`~x`) - LuaConcat / LuaConcatMethod (`a .. b`) - LuaLength / LuaLengthMethod (`#x`) + +:::note +You can also map functions to table accessors (`__index` and `__newindex`). See [Lua Table Types](#lua-table-types). +::: + +## Lua Table Types + +The `LuaTable` type is provided to allow direct creation and manipulation of Lua tables. This is useful if you want to use a table that uses types other than string for its keys, as that is not supported by Typescript. Calls to `get` and `set` on the table will transpile directly to `value = table[key]` and `table[key] = value`. + +Example: + + + +```ts +const tbl = new LuaTable(); + +tbl.set("foo", "bar"); +console.log(tbl.get("foo")); + +const objectKey = {}; +tbl.set(objectKey, "baz"); +console.log(tbl.get(objectKey)); + +tbl.set(1, "bah"); +console.log(tbl.length()); +``` + +```lua +tbl = {} + +tbl.foo = "bar" +print(tbl.foo) + +objectKey = {} +tbl[objectKey] = "baz" +print(tbl[objectKey]) + +tbl[1] = "bah" +print(#tbl) +``` + + + +`LuaTable` can also be restricted to use only certain types as keys and values: + +```ts +const tbl = new LuaTable(); +``` + +If you have a type that uses non-string keys, you can use `LuaTableGet` and `LuaTableSet` function types to declare your own getters & setters, similar to [Operator Map Types](#operator-map-types). + +Example: + + + +```ts +interface Id { + idStr: string; +} + +interface IdDictionary { + get: LuaTableGetMethod; + set: LuaTableSetMethod; +} + +declare const dict: IdDictionary; +const id: Id = { idStr: "foo" }; +dict.set(id, "bar"); +console.log(dict.get(id)); +``` + +```lua +id = {idStr = "foo"} +dict[id] = "bar" +print(dict[id]) +``` + + + +That example uses the `Method` versions of `LuaTableGet` and `LuaTableSet`. There are also stand-alone versions. + +Example: + +```ts +declare const idGet: LuaTableGet; +declare const idSet: LuaTableSet; +idSet(dict, id, "bar"); +console.log(idGet(dict, id)); +``` + +```ts +declare namespace IdDictionary { + export const get: LuaTableGet; + export const set: LuaTableSet; +} +IdDictionary.set(dict, id, "bar"); +console.log(IdDictionary.get(dict, id)); +```