Feedback on strictly typed OOP class template

I’m looking for feedback mainly from those of us who edit scripts in Studio, prefer strict mode, use OOP, and like intellisense.

Here’s the template:

--!strict
local MyClass = {}
MyClass.__index = MyClass

export type ClassImpl = {
	
}
export type ClassType = typeof(setmetatable({} :: ClassImpl, MyClass))
export type MyClass = ClassType

function MyClass.new(): MyClass
	local self: ClassImpl = {
		
	}
	
	setmetatable(self, MyClass)
	
	return self
end

function MyClass.method(self: ClassType)
	
end

return MyClass

It’s pretty much the Plant reference project’s typed class syntax, with a few changes. I’m looking to see if there’s any more improvements that can be made. I really like it so far…

An explanation of the changes:

  1. ClassImpl type is there so I can define self with autocompletion during MyClass.new(), like this:


    Because self is defined as ClassImpl, the typechecker really doesn’t let me forget anything that’s supposed to be there from the moment local self: ClassImpl is defined.

  2. ClassType is redefined as MyClass, and MyClass is returned by the .new() constructor. This is just to make the type tooltip thing less confusing when using the class elsewhere, like this:


    Just like the Plant reference project, I define example as type MyClass.ClassType. I think it looks good that way and makes it easy to read.
    However, when hovering over the example variable, it gives me this:
    image
    It becomes a bit unwieldy when you have multiple variables of different classes, and they all say just ClassType… The solution I’ve found was just to redefine ClassType as a new type with the class name, as export type MyClass = ClassType. I admit this is not really necessary, but I think it’s nice😅


What do you guys think? Would appreciate any responses. Thanks!