Differentiating type class methods from "." indexed functions

You can sort of do this with typecasting. Here’s how I set up my own classes, basically:

-- Class is its own type
export type Class =
{
    -- Methods
    Method: (self: Class) -> ();
    -- Members
    someValue: number;
}
-- Separate static functions from class methods
type Static =
{
    new: () -> Class;
}
-- Implementation is completely separate
type ClassImpl =
{
    __index: ClassImpl;
} & Static & Class -- Union the static functions and the class methods

local Class: ClassImpl = {} :: ClassImpl
Class.__index = Class

function Class.new(): Class
    local self: Class = {
        someValue = 2;
    } :: Class
    setmetatable(self :: any, Class)
    return self
end

-- VERY IMPORTANT!
-- The typecast makes it so only the static functions are exposed to other scripts
return Class :: Static

So, only your methods and members are exposed for anything that is of type Class. But, your static functions like the constructor are limited to whatever requires the module.

3 Likes