TypeScriptToLua Documentation

website·Indexed 29 days ago

https://typescripttolua.github.io/

Documentation for TypeScriptToLua (TSTL), a transpiler that converts TypeScript to Lua. It includes guides on installation, project setup, high-level and printer APIs, plugin development, and language extensions like LuaMultiReturn. The docs cover feature support, JSX integration as of version 0.42.0, compiler annotations such as @compileMembersOnly, and the use of declaration files for external Lua APIs.

Tokens
13.8K
Snippets
83
Records
105
Agent score
70%

What's inside TypeScriptToLua

  1. Use TypeScript declaration files for existing Lua APIs

    TSTL can be used in any environment that accepts Lua. You can provide type safety for existing Lua APIs by creating TypeScript declaration files (.d.ts), which allows for static checking and improved IDE support (like refactoring and autocomplete) during Lua application development.
  2. Understand tstl library types for npm publishing

    There are two types of libraries that can be published via npm for use with TypeScriptToLua:

    1. Type declaration libraries: Provide only ambient types. These contain no executable code.
    2. Lua libraries: Provide actual Lua code that can be imported and executed by other tstl projects.
  3. Use LuaPrinter to convert Lua AST to string

    The LuaPrinter class is responsible for taking a Lua AST and printing it to a string. It implements the visitor pattern, where methods visit specific AST nodes to produce SourceNode objects. This process automatically generates the correct mappings for the resulting source map.
    // Example instantiation
    const printer = new LuaPrinter(options, emitHost, fileName);
    const result = printer.print(block, luaLibFeatures);
    
    // result contains:
    // result.code: The generated Lua code string
    // result.sourceMap: The source map string
    // result.sourceMapNode: The SourceNode object
  4. Create ambient declaration files for Lua environments

    Declaration files use the .d.ts extension and contain 'ambient' code—code that exists only at compile-time to inform the TypeScript compiler about the types of external functions, modules, and variables in the target Lua environment. Ambient declarations are not emitted into the generated .lua files. While typically placed in .d.ts files, ambient declarations can also be written inside standard .ts files.
  5. Declare a callable table with static methods

    For Lua tables that are both callable (via __call) and have static methods, define a constructor interface that includes both a call signature and the method definitions.
    interface Box {
      get(): string;
    }
    
    interface BoxConstructor {
      (this: void, value: string): Box;
      getInstance(): Box;
    }
    
    declare var Box: BoxConstructor;
    
    // Usage
    const box = Box("foo");
    box.get();
    Box.getInstance().get();
  6. Integrate type declarations for Lua environments

    To enable type checking for external Lua functions and variables, install the relevant type declaration package from npm and add the package name to the types array within compilerOptions in tsconfig.json.

    Official declarations for the Lua standard library are available via the lua-types package, which is useful for low-level Lua operations.

  7. Import JSON files in TypeScriptToLua

    TypeScriptToLua allows importing JSON files by translating the JSON content into a Lua file and including it in the transpiler output. To use this feature, you must configure your tsconfig.json to allow JSON module resolution and use the node module resolution strategy.
    {
      "compilerOptions": {
        "moduleResolution": "node",
        "resolveJsonModule": true
      }
    }
  8. Publish and install TypeScript declarations via npm

    TypeScript declaration packages can be published to npm for distribution. Users can install these declarations as development dependencies and link them to their project via the types array in tsconfig.json.
    # Publishing steps
    npm init
    npm login
    npm publish --dry-run   # Preview files to be published
    npm version 0.0.1       # Update version in package.json
    npm publish             # Final publish
    
    # Installation step
    npm install <declarations> --save-dev
    // tsconfig.json
    {
      "compilerOptions": {
        "types": ["declarations"]
      }
    }
  9. Publish a tstl library to npm

    When publishing your tstl library:

    • Files like package.json and README.md are always published regardless of the files array.
    • Dependencies listed in devDependencies are not available at runtime.
    • The tsconfig.json file does not need to be published as it is not used by the consumer.

    Recommended workflow:

    1. Run npm publish --dry-run to verify the file list.
    2. Run npm publish to upload the package.
    npm publish --dry-run
    npm publish
  10. Import a Lua module that exports an array

    When a Lua module exports an array without named imports or a default export, use the export = syntax in the declaration file. In the TypeScript code, use the import * as syntax to access the array.
    -- things.lua
    return {
        { foo = 123, bar = 456 },
        { foo = 789, bar = 987 },
    }
    // things.d.ts
    interface Thing {
      foo: number;
      bar: number;
    }
    
    declare const things: Thing[];
    export = things;
    
    // main.ts
    import * as things from "./module";
    print(things[0].foo); // Prints "123"
  11. Manage imports and re-exports in declaration files

    Declaration files support standard TypeScript import and export syntax. You can import global declarations from other files or re-export specific types to make them available to other modules. Additionally, import statements can be placed inside ambient modules and namespaces to provide type dependencies for specific functions.
    import "./lib";
    // All global declarations in lib will be included with this file
    
    export { Player } from "./Entities";
    // The Player declaration is re-exported from this file
    
    declare module "mymodule" {
      import * as types from "types";
      export function getType(): types.Type;
    }