How to automate construction of types?

Hello, as suggested in the title, I’m trying to construct a type automatically. This is easier to show with an example what I mean so I’ll leave one below.

--this is *not* in !strict

local Type = {} --will convert this into type later on
local properties = {"Name", "UserId", "Character", "Health", "Damage", "LootLuck", ...} --properties of player along with some custom ones.

for _, propertyName in pairs(properties) do
	pcall(function() --pcall incase we try to reference a property we don't have permissions for
		local v: typeof(player[propertyName]) = true --setting it to true because the actual value doesn't matter afaik
		Type[propertyName] = v --basically trying to do {[propertyName]: typeof(property)} **how would i do this?
	end)
end
type Type = Type --convert to type
local player: Type = {}
--autocomplete doesn't function at all on the table

I’ve also tried:

local player: Player = {}

Which works to some extent, however it blocks out any custom properties from the autocomplete, making the entire thing identical to the actual instance and removing any point there was.

My goal is to have a type that has all the default properties n’ stuff from the player (without having to manually type all of it into a script), but also with the capability to add custom ones recognized by the autocomplete.
Any clue on how to do this?

I don’t believe that is possible unless you explicitly define or filter them. This can be done with something like

if InstanceObject:IsA("Player") then
--your code
--InstanceObject.UserId will autocomplete
end

I see what you are trying to do here.
In a sense, it is basically the same thing as doing:

do
	local InstanceObject: Player = InstanceObject
	--your code
end

However there’s a few issues I caught with this:

  1. As mentioned previously in my post I have already tried setting the type to Player which works to some extent, but in the end just makes the entire thing pointless.
  2. In my case InstanceObject is not an instance and you cannot call :IsA(...) on it.
  3. Even if by some miracle you were able to call :IsA(...) on it, it does not work as intended and rather completely removes the autocomplete from the instance:
    image

A better way of doing this would be to just set the type to Player which brings me back to my first point.
Manually setting the type:
image

In that case, it’s probably not possible. You could try, however, to make a table of the types you’re going to use like this:

local types = {
'Player',
'Model',
'any'
--etc.
}

though I don’t know if this would work.

Uh… could you explain more about the concept please?

Types are only used to analyse your code before run time, meaning you cannot generate types on fly.

So, you must either have a complete table ready for luau to recognise the structure before running the game, or define your types manually.

That said, you could instead use type intersection feature by using & to assign combined types, like so:

--!strict 

type playerExtension = {hello: boolean, adminRank: number}

local player: Player & playerExtension = -- some player

print(player.hello) -- this will autocomplete. though it will fail because there is no such property called hello for Player class. 
print(player.adminRank) --> will also autocomplete, but will fail in runtime cause again, there is no such property called adminRank for Player class.

However, your real solution to this problem would probably to wrap the player class if you absolutely need to extend the functionality of Player class, which you can read about more in this post: Wrapping instances with Roblox's lua? - Scripting Helpers

1 Like

Thank you for this information, I didn’t realize that you could intersect instance type (I guess it’s technically a table type) and table types. This also saves me a lot of time trying to pursue generating types on the ‘fly’.

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