Autocompletion and modules

Hi, devs !

I’m made a module script to easily get my modules which is called Services.

I mean to get a “Service” I need to do this :

local MyService = Services:GetService("MyService")

But the problem is that autocomplete stop showing me things.

I mean if I do this, it’ll show anything :

MyService:
MyService.

So I have two questions, how to make autocomplete work, and how did roblox manage to make their function game:GetService("ServiceName") which suggest a service name with autocomplete and when u have the service autocomplete work.

Thanks you very much for the replies !
Sorry for my bad english and have a nice day !

1 Like

Alright lets take a look at the module first

3 Likes

The types are defined internally within the type analysis for each class. You can replicate it as well, you’d just have to manually define the types for each service

type GetService = ((name: "MyService") -> MyService) & ((name: "TestService") -> TestService)

local fetch: GetService = nil
fetch( -- it will give you "MyService" and "TestService" as options you can select, and based on what you select, the return type of 'fetch' will change
2 Likes

I might sound stupid but I can’t figure out how to assign the type to the module :skull:

1 Like
type GetService = 
     ((name: "MyService") -> typeof(require(path.to.module))) & -- easier to look at
     ((name: "TestService") -> TestService)

Or, if you don’t (or can’t) call require on the module, you can manually define what the service is:

type MyService = {
    MyMethod: (...any) -> any,
    Property: number
}

type GetService = 
     ((name: "MyService") -> MyService) & -- easier to look at
     ((name: "TestService") -> TestService)
1 Like

I dont think u understood what I asked, I mean this :

type GetService = ((name: "MyService") -> ModuleScript) & ((name: "TestService") -> ModuleScript) & ((name: "Another") -> ModuleScript)
type Services = {GetService}

return Services :: Services

If Services is a table (my original method assumed you were using a function), you can do this alternatively:

type ServiceList = {
   ["MyService"]: typeof(require(path.to.module)), -- (or manually define)
   ["TestService"]: ..., -- so on and so forth
   ["Another"]: ...
}

return Services :: ServiceList

If this still isn’t neccessarily the way your services are handled, can I see how you’re fetching them so I could help you more efficiently for your issue?

1 Like

Services is the module script, and :GetService() is a method :

local Services = {}

local Modules = {}

for _, Module in pairs(script:GetChildren()) do
	if Module:IsA("ModuleScript") then
		Modules[Module.Name] = require(Module)
	end
end

function Services:GetService(Name)
	return Modules[Name]
end

type GetService = ((name: "MyService") -> ModuleScript) & ((name: "TestService") -> ModuleScript) & ((name: "Another") -> ModuleScript)
type Services = {GetService}

return Services :: Services
local Services = {}
local Modules = {}

for _, Module in pairs(script:GetChildren()) do
	if Module:IsA("ModuleScript") then
		Modules[Module.Name] = require(Module)
	end
end

type Services = typeof(Services)
type GetService = -- i assume not all of these modules exist, but this is what the type definition should look like (as an example)
     ((self: Services, name: "MyService") -> typeof(require(script.MyService))) & 
     ((self: Services, name: "TestService") -> typeof(require(script.TestService))) & 
     ((self: Services, name: "Another") -> typeof(require(script.Another)))

Services.GetService = function(self, name)
	return Modules[Name]
end :: GetService -- assign the 'GetService' type here, so now when you're using this method, you can see all the listed services and selecting one will correctly give you the service's module

return Services

I wanted to just do Module.ServiceName for the GetService types, but because of the way the type analyzer works, you would just get any as the result (which doesn’t help your case). So, you would have to manually call require for each of the modules in the list (like I did)

local Services = require(path.to.ServicesModule)
local MyService = Service:GetService( -- you can see all the services, and when you select "MyService", it will correctly give you the ModuleScript content of "MyService"

Example:

local MyService = Service:GetService("MyService")
MyService. -- you can see all the properties and methods for the service
MyService: -- same here
2 Likes

Thanks you very much !
Have a nice day !

Just a last thing, is there a chance to replicate what roblox do :
I mean having this :

Instead of this :

I mean by this a list of all the services, return type as instance and name as a string.

Thanks you very much for ur time, it help me very much !

EDIT : My bad theres already the list thingy

Unfortunately, the other options are not possible using the type analyzer just yet; the list of options is the only thing possible right now (the type analyzer for engine-level methods pull directly from the internal documentation I believe)

1 Like

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