Just add type annotations to the parameters: player : Player, receiptInfo: ReceiptInfo etc because currently it doesn’t know the types of these so it marks them as unknown and unknown doesn’t match the type of the callback.
Doing this fixes the error, but it doesn’t make any sense, I already should be already do this when I write local ProductHandler = {} :: ProductHandlerImpl right?
No, you cast the array to a producthandlerimpl so the type analyser expects two properties one named productcallbacks, okay inside of it the analyser expects only fns of type product callback, so if you try to access from productcallbacks it will give you intellisense for that type, but trying to assign an fn not of product callback will error because even though the array is of type product callback, the function isn’t. I think it would’ve worked normally as well if you cast the fn to product callback but idk.
You can easily test this by replicatin the case with a simplified example:
--!strict
local ins : Instance = Instance.new("Part")
ins.ClassName --when typing the . Aka reading you get intellisense for instance
ins = 5--the type analyser complains, because even though ins is of type Instance, 5 isn't.
Hope this helps, I’m bad at explaining things. I’m hoping the example carries this explanation.
Edit: type annotations specify what type it expects to be there, but that doesn’t mean whatever you assign to it will suddenly be of that type.
Ah I see, so luau will treat function parameters as unknown unless I explicitly write it. So, what you said is the solution. However, I am just wondering if there is a way I can make it so that I don’t have to keep writing the types of each callback if I have multiple of them.
Why don’t you want to write the types out for each parameter? That’s the best solution to your problem that doesn’t involve any sort of weird or unnecessary casting, and you should be annotating parameters for all functions regardless when using types.
ProductHandler.ProductCallbacks = {
[12345] = function(player: Player, receiptInfo: ReceiptInfo, data: DataManager.DefaultData)
data.coins += 100
return true
end
} -- Fine