Luau type checking issue for an array with mixed types, specific # of values

So basically I have this Luau type checking warning and it’s driving me crazy

image

Code
--!strict
type Cost = {string, number} -- "a: Unknown global 'number'"

export type ItemClass = {
    Type: number,
    Level: number,
    IconId: number,
    Cost: Cost
}

local item: ItemClass = {
    Type = 1,
    Level = 1,
    IconId = 123,
    Cost = {"Gold", 100}
}

local function a(b: ItemClass)
    (b.Cost[1]):format()
end

Cost should only ever be an array, with the first index a string, and the second index a number.

If I use a union instead and I try to run function a, it would error because Cost under b (type is ItemClass) is string | number, meaning it will warn me that it could be a number, and that I can’t run format on a number. The thing is, Cost[1] will always be a string, and Cost[2] will always be a number. There will never be more than 2 indexes, and it must be a regular array.

Only resource I can find that relates to this is here, which basically tells me it might not be possible yet (can’t use number literals for the index):
https://devforum.roblox.com/t/luau-type-checking-release/878947/78

Is this possible at the moment? Or will I just have to use a union, and find some way to silence the warning if I get one?

Luau type interface only allows a single type to be declared for an entire array. The way you would get around this is by using unions and type assertation operator (::) whenever necessary:

type Cost = {string | number}

local cost: Cost = {"test", 12}
print(string.format("%s:%g", cost[1] :: string, cost[2] :: number))

You could also use string interpolation if you’re not doing anything special, like specifying number precision or width, with the string.format function and not use the type assertation altogether:

print(`{cost[1]}:{cost[2]}`)
4 Likes

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