How to get autocompletion with self in methods

so in this module script the CreateDialogue function constructs a dialogue but when i use methods with dialogue no autocompletion happen i tried the new beta type solver and the old one but none worked considering that self is defined as dialoged when setting it as a metatable

--!strict
local CollectionService = game:GetService("CollectionService")

-- ////
export type dialogue = {
	HeadText :string, 
	BodyText :string, 
	TypeWriter :{mode : typeWriterMode, speed :number, clickSkip : number},
	Replies : {[string] : () -> ()},
}

type typeWriterMode = "None" | "Basic" | "CursorBlink" | "Human"


-- ////
local DialogueService = {} -- dialogue class that will create dialogues
local dialogue = {} -- dialogue object
dialogue.__index = dialogue

--////

-- a table to store gui elements
local elements = {
	ScreenGui = CollectionService:GetTagged("Dialogue_ScreenGui"),
	HeadText = CollectionService:GetTagged("Dialogue_HeadText"), -- Head
	BodyText = CollectionService:GetTagged("Dialogue_BodyText"), -- Body
	RepliesFrame = CollectionService:GetTagged("Dialogue_RepliesFrame"), -- a scrolling frame that hold replies
	
	ReplySample = CollectionService:GetTagged("ReplySample") -- a reply sample will be cloned to create replies
}

-- Enums Table
DialogueService.Enum = {
	TypeWriterMode = {
		None = "None",
		Basic = "Basic",
		CursorBlink = "CursorBlink",
		Human = "Human",
	}
}

function DialogueService.CreateDialogue(headText :string, bodyText,typeWriter : {mode : typeWriterMode, speed :number, clickSkip : number}, replies : {[string] : () -> ()})
	local self :dialogue = {
		HeadText = headText,
		BodyText = bodyText,
		TypeWriter = typeWriter,
		Replies = replies,
	}
	return setmetatable(self, dialogue)
end

function dialogue:Play()
	self. -- NO Auto Complete Here
end

return DialogueService

{47F8D829-5E28-4F2B-95E9-EA44B2231E2E}

while
{BEB4E7EB-C5F2-4821-A302-91BB5959783E}

the only way i found to get autocompletion is

local self :dialogue = self

but that doesn’t sound like the correct way to do it + local self is a copy of self and not self, so I don’t like doing that

any help is appreciated

You can define the class type, and then for all colon operator functions, you will need to manually define self as the first argument.

local MyClass = {}
MyClass.__index = MyClass

-- define the class type
export type ClassType = typeof(setmetatable({} :: {
	Value: number,
}, MyClass))

function MyClass.new(num: number): ClassType -- define return type for typechecking object
	local self = setmetatable({}, MyClass) :: ClassType -- allows typechecking in constructor
	
	self.Value = num
	
	return self
end

-- manually define the self argument for typechecking
function MyClass.GetValue(self: ClassType): number
	return self.Value
end

return MyClass
local obj = MyClass.new(10)
local value = obj:GetValue()
print(value) -- 10
1 Like

thank you that worked very well
i modified the object type to include the function as if it takes self : dialogue and changed the mt name to dialogueMeta while annotating it to dialogue it shows autocomplete without defining self:dialogue as the 1st argument

local DialogueService = {} -- dialogue class that will create dialogues
local dialogueMeta = {} :: dialogue -- dialogue object
dialogueMeta.__index = dialogueMeta

export type dialogue = typeof(setmetatable({} ::{
	HeadText :string, 
	BodyText :string, 
	TypeWriter :{mode : typeWriterMode, speed :number, clickSkip : number},
	Replies : {[string] : () -> ()},
	Play : (self : dialogue) -> (),
	[any] : any
},
dialogueMeta))

function DialogueService.CreateDialogue(
	headText :string,
	bodyText,
	typeWriter : {mode : typeWriterMode, speed :number, clickSkip : number},
	replies : {[string] : () -> ()}) : dialogue
	
	--//// Code
	
	local self = {
		HeadText = headText,
		BodyText = bodyText,
		TypeWriter = typeWriter,
		Replies = replies,
		isPlaying = false,
	}
	return setmetatable(self , dialogueMeta) :: dialogue
end

function dialogueMeta:Play()
	self. -- autocomplete showing here
end

You still need to call the function with the colon. The colon implicitly passes self as the first argument, but can you manually specify the self argument to allow for typechecking. For example, the following code is functionally equivalent:

function MyClass:Play()
    print(self)
end
function MyClass.Play(self)
    print(self)
end

And the same goes for the calling the function, where the following code is also functionally equivalent:

local obj = MyClass.new()
obj:Play()
local obj = MyClass.new()
obj.Play(obj)
1 Like

yes but you cannot manually define self in a method as you can in a normal function ik that they will behave the same but MyClass:Play() looks cleaner than MyClass.Play(self : ClassType) in my opinion and the way to annotate it in a method: was to annotate the MyClass that it have a function called play that have 1st argument of type ClassType

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.