You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hey, so I was trying to write a module script which would have a number of functions we'd normally get out of language libraries in OOP languages for arrays, but in this case adapted for Dictionaries.. So I did the following minimal reproduction of this error:
--!strict
type DictionaryImpl<K,V> = {
__index: DictionaryImpl<K,V>,
Get: (self: Dictionary<K, V>, key: K) -> V,
}
type Dictionary<K, V> = typeof(setmetatable({} :: {[K]: V}, {} :: DictionaryImpl<K,V>))
function New<K,V>(objects: {[K]: V}): Dictionary<K,V>
local newMetatable: DictionaryImpl<K, V> = {} :: DictionaryImpl<K, V>
function newMetatable:Get(key: K)
return self[key]
end
newMetatable.__index = newMetatable
return setmetatable(objects, newMetatable)
end
type stuffType = {
[string]: number
}
local testStuff: stuffType = {stuff = 123}
local testDictionary = New(testStuff)
print(testDictionary:Get("stuff"))
When doing testDictionary:Get("stuff"), it works as expected and returns me the value = 123, but when I hover my mouse over testDictionary it just says the type is of Dictionary rather than Dictionary<string, number> which it should since it is inferring those types quite well (In this case, intelisense tells me that Get receives a parameter key of type string and returns something of type number, so it is correct). Personally that wouldn't be a problem but what is a problem is that when I do write testDictionary:Get("stuff") it tells me that "Cannot call non-function member".
So my two problems boil down to this:
It tells me that Get is a non-function member, when it is defined as a function.
Intelisense displays __index as a member of my table.. shouldn't this be hidden?
I do however wanna clarify some things that I have done that I know are bizarre. The reason why I am defining the metatable contents (such as __index and the Get method) is that if I do in the conventional way (as described in Luau's type checking documentation and showcased below), then I would have to instantiate my table Dictionary as being local Dictionary: Dictionary<unknown, unknown> = {} :: DictionaryImpl<unknown,unknown>.. and from this point forward I lose all type inference for K and V, which is one of my main goals with this whole thing to begin with.
type AccountImpl = {
__index: AccountImpl,
new: (name: string, balance: number) -> Account,
deposit: (self: Account, credit: number) -> (),
withdraw: (self: Account, debit: number) -> (),
}
type Account = typeof(setmetatable({} :: { name: string, balance: number }, {} :: AccountImpl))
-- Only these two annotations are necessary
local Account: AccountImpl = {} :: AccountImpl
Account.__index = Account
-- Using the knowledge of `Account`, we can take in information of the `new` type from `AccountImpl`, so:
-- Account.new :: (name: string, balance: number) -> Account
function Account.new(name, balance)
local self = {}
self.name = name
self.balance = balance
return setmetatable(self, Account)
end
-- Ditto:
-- Account:deposit :: (self: Account, credit: number) -> ()
function Account:deposit(credit)
self.balance += credit
end
-- Ditto:
-- Account:withdraw :: (self: Account, debit: number) -> ()
function Account:withdraw(debit)
self.balance -= debit
end
local account = Account.new("Alexander", 500)
The text was updated successfully, but these errors were encountered:
Hey, so I was trying to write a module script which would have a number of functions we'd normally get out of language libraries in OOP languages for arrays, but in this case adapted for Dictionaries.. So I did the following minimal reproduction of this error:
When doing
testDictionary:Get("stuff")
, it works as expected and returns me the value = 123, but when I hover my mouse overtestDictionary
it just says the type is ofDictionary
rather thanDictionary<string, number>
which it should since it is inferring those types quite well (In this case, intelisense tells me that Get receives a parameter key of type string and returns something of type number, so it is correct). Personally that wouldn't be a problem but what is a problem is that when I do writetestDictionary:Get("stuff")
it tells me that "Cannot call non-function member".So my two problems boil down to this:
I do however wanna clarify some things that I have done that I know are bizarre. The reason why I am defining the metatable contents (such as __index and the Get method) is that if I do in the conventional way (as described in Luau's type checking documentation and showcased below), then I would have to instantiate my table Dictionary as being
local Dictionary: Dictionary<unknown, unknown> = {} :: DictionaryImpl<unknown,unknown>
.. and from this point forward I lose all type inference for K and V, which is one of my main goals with this whole thing to begin with.The text was updated successfully, but these errors were encountered: