Type annotations affecting script functionality

I have a script that gets a team by its brickcolor.

local function GetTeamByBrickColor(brickcolor: BrickColor)
	for i, team in pairs(Teams:GetTeams()) :: {Team} do
		if team.TeamColor == brickcolor then
			return team
		end
	end
	
	error(`No team with brickcolor {brickcolor.Name}`)
end

When run, with the type annotation {Team}, I get the error:

By simply removing the annotation, it works fine.

Extra info:
I’m using the run test (so only server, no clients).

How to repo:
Create an empty place.
Create two server scripts.
In one server script, paste in this code:

local function GetTeamByBrickColor(brickcolor: BrickColor)
	for i, team in pairs(Teams:GetTeams()) :: {Team} do
		if team.TeamColor == brickcolor then
			return team
		end
	end
	
	error(`No team with brickcolor {brickcolor.Name}`)
end

In the other script,

local function GetTeamByBrickColor(brickcolor: BrickColor)
	for i, team in pairs(Teams:GetTeams()) do
		if team.TeamColor == brickcolor then
			return team
		end
	end
	
	error(`No team with brickcolor {brickcolor.Name}`)
end

Select the Run option in testing, then run.

Expected behavior

I expect annotations to not affect how a script functions.

2 Likes

It should be important to note that regular Test does not have this issue.
I’m wrong. It affects Test too.

1 Like

Thank you for the report.

This is by design, asserting a type of the expression value discards all extra values, just like (pairs(Teams::GetTeams())) will do.
This is because you are saying that the expression has a type of a single value, not a type pack of values.

1 Like

In addition–your type is in the wrong place. pairs(Teams:GetTeams()) :: { Team } typecasts the result of pairs.

What you want is pairs(Teams:GetTeams() :: { Team }), or our recommendation: ditching pairs altogether and going with for i, team in Teams:GetTeams() :: { Team } do

1 Like

I’m confused. So typecasting does affect code execution?

Or rather, does change how it gets compiled?

The key thing you’re missing is that pairs() returns more than one value. :: T will only take the first.

local function f()
  return 1, 2
end

print(f()) -- 1  2
print(f() :: number) -- 1
1 Like

That makes it clearer, thanks. Is this documented somewhere? I couldn’t find this information.

1 Like

It’s here, though the documentation is pretty beefy so I don’t blame you :slight_smile:

1 Like