#how to make this typecheck?

1 messages · Page 1 of 1 (latest)

velvet jay
#

i have a small UI library that mostly returns setmetatable(SomeTable, { __index = SomeWidget (extends GuiBase) }). how do i make a type Widget that accepts both regular widgets (i.e. GuiBase) and the table-with-metatable?

example:

type UIButton = setmetatable<{
  Label: TextLabel,
}, { __index: ImageButton }>

function createButton(label: string): UIButton
  local self = Instance.new "ImageButton"
  local wrapper = {}

  self.Image = "blah blah blah"
  -- blah blah blah

  wrapper.Label = Instance.new "TextLabel"
  wrapper.Label.Parent = self

  return setmetatable(wrapper, { __index = self })
end

-- help with this pls
type Widget = GuiBase | setmetatable<{}, { __index: GuiBase }>

function addPadding(pad: number, child: Widget): UIPadding
  local self = Instance.new "UIPadding"
  -- blah blah blah
  return self
end

local b = createButton "Click on me"
local padded = addPadding(6, b) -- typechecker fails because UIButton cant be converted to Widget :/

and no, "just dont have --!strict" or "type Widget = any" is not a solution

velvet jay
#

actually i'm pretty sure this is impossible without covariance/contravariance in generics or any :/

somber iron
#
type Widget = GuiBase & {
   Label: TextLabel
}
velvet jay
somber iron
velvet jay
#

so Widget = UIButton | UIScrollingList | ...

somber iron
#

Well yea

#

While looking ugly I dont think you have any other methods

#

Unless you manually make the UIBase

#

Also the type checking is yet to be able to actually predict what type would be returned from methods/functions

#

So you are at best making only some of the properties visible or all of them