When using a custom iterator which is implemented with coroutine.wrap, the type checker gives the error: "Type Error: next() does not return enough values":
This is compared to the old type checker providing the correct types
Code
--!strict
local function CustomIterator()
return coroutine.wrap(function()
coroutine.yield(1, "foo")
coroutine.yield(2, "bar")
end)
end
for i: number, v: string in CustomIterator() do
end
This lead me to set the return type of the CustomIterator to “any”, however this came with its own bug that popped up where the defined types of the loop variables would become “any” despite being typed.
Once again this is not an issue with the old type solver
Code
--!strict
local function CustomIterator(): any
return coroutine.wrap(function()
coroutine.yield(1, "foo")
coroutine.yield(2, "bar")
end)
end
for i: number, v: string in CustomIterator() do
-- This should clearly warn!
local sound: Sound = v
end
I would assume this is not intended as I defined “v” to be a string.
This case occurs in any case where a variable with “any” is passed into a for loop, including when using pairs.
More Examples
--!strict
local foo: any = {}
for i: number, v: string in foo do
-- This should clearly warn!
local sound: Sound = v
end
--!strict
local foo: any = {}
for i: number, v: string in pairs(foo) do
-- This should clearly warn!
local sound: Sound = v
end
Hopefully these couple of things get fixed (especially passing “any” into a for loop and types being nullified, since I can see that probably causing some issues when using libraries).
Workaround for coroutine iterators
Workaround I ended up using was to cast the returned coroutine as the function with return types.
--!strict
local function CustomIterator(): () -> (number, string)
return coroutine.wrap(function()
coroutine.yield(1, "foo")
coroutine.yield(1, "bar")
end) :: ()->(number, string)
end
for i: number, v: string in CustomIterator() do
print(i, v)
end








