Search code examples
luarobloxluauroblox-studio

How to type annotate a Module Script in Luau?


I'm currently making a strict type checked script but can't find a way to type annotate a variable that requires a Module Script without using the type any which is bad practice.

DoSomethingScript:

--!strict

local moduleScript: any = require(script.SomethingModule) -- How do I change the any type here?

moduleScript:DoSomething()
moduleScript:NotMethodAndShouldRaiseWarning() -- Using the any type doesn't give warnings for non-existant methods

SomethingModule:

local SomethingModule = {}

function SomethingModule.DoSomething()
    print("Doing something")
end

return SomethingModule

I tried looking at the Roblox Creator Hub documentation and Luau website for how to type annotate a Module Script but can't find anything about it.

So how would I define the type for a Module Script?


Solution

  • You are looking for the export type keywords.

    The Luau documentation has a section for 'Module Interactions' and you can pair that with the section for 'Adding types for faux object oriented programs' which you can use to describe your ModuleScript's returned table.

    For example, in your ModuleScript :

    -- define the shape of the ModuleScript's returned table
    export type MathUtilImpl = {
        add : (a: number, b: number)-> number,
        subtract : (a: number, b: number) -> number,
    }
    local MathUtil : MathUtilImpl = {}
    
    function MathUtil.add(a, b)
        return a + b
    end
    
    function MathUtil.subtract(a, b)
        return a - b
    end 
    
    return MathUtil
    

    I'm not using --!strict in the ModuleScript because I didn't want to define everything on the local MathUtil line. But the documentation has suggestions on how to do it.

    Including your ModuleScript will bring the exported types with it. Then, Roblox's linter will give warnings if you are using something incorrectly.

    Then in your Script :

    --!strict
    local MathUtil = require(script.ModuleScript)
    print(MathUtil.add(1, 2)) -- returns 3
    print(MathUtil.subtract("foo", "bar")) -- gives errors 'Type "string" could not be converted to number'
    print(MathUtil.multiply(3, 4)) -- gives error 'Key "multiply" not found on table "MathUtil"'