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 !
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
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?
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
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)