Deprecate create() overloads

Closes #70
This commit is contained in:
centauri 2026-04-29 21:33:29 +01:00
parent 7deae9c9f6
commit 19eaeb424f
4 changed files with 33 additions and 74 deletions

View file

@ -12,6 +12,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- `branch()` is now allowed to be used within a reactive scope. - `branch()` is now allowed to be used within a reactive scope.
### Deprecated
- `create()` overloads. Supported is now only `create(class)(props)`.
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
## [0.4.0] - 2026-01-17 ## [0.4.0] - 2026-01-17

View file

@ -5,11 +5,10 @@ local defaults = require "./defaults"
local apply = require "./apply" local apply = require "./apply"
local flags = require "./flags" local flags = require "./flags"
local ctor_cache = {} :: { [string]: (AnyProps) -> Instance } local function create_constructor_for_class(class: string): ({ [unknown]: unknown }) -> Instance
local function lazy_init(_, class: string) local function constructor(properties: { [unknown]: unknown }): Instance
local function ctor(properties: AnyProps): Instance
local ok, instance: Instance = pcall(Instance.new, class :: any) local ok, instance: Instance = pcall(Instance.new, class :: any)
if not ok then error(`invalid class name { class }`, 0) end if not ok then error(`invalid class name {class}`, 0) end
if flags.defaults then if flags.defaults then
local default: { [string]: unknown }? = defaults[class] local default: { [string]: unknown }? = defaults[class]
@ -23,28 +22,34 @@ local function lazy_init(_, class: string)
return apply(instance, properties) return apply(instance, properties)
end end
ctor_cache[class] = ctor return constructor
return ctor
end end
setmetatable(ctor_cache, { __index = lazy_init })
local constructor_cache = {} :: { [string]: ({ [unknown]: unknown }) -> Instance }
-- todo: remove support for different overloads -- todo: remove support for different overloads
local function create(class_or_instance: string|Instance, properties: AnyProps?): ((AnyProps) -> Instance) | Instance local function create(class_or_instance: string|Instance, properties: { [unknown]: unknown }?): unknown
if type(class_or_instance) ~= "string" and typeof(class_or_instance) ~= "Instance" then if type(class_or_instance) ~= "string" and typeof(class_or_instance) ~= "Instance" then
error("bad argument #1, expected string or instance, got " .. typeof(class_or_instance), 0) error("bad argument #1, expected string or instance, got " .. typeof(class_or_instance), 0)
end end
local ctor = if type(class_or_instance) == "string" local constructor: ({ [unknown]: unknown }) -> Instance
then ctor_cache[class_or_instance] if type(class_or_instance) == "string" then
else function(properties) constructor = constructor_cache[class_or_instance]
local clone = class_or_instance:Clone() if not constructor then
if not clone then error "attempt to clone a non-archivable instance" end constructor = create_constructor_for_class(class_or_instance)
return apply(clone, properties) constructor_cache[class_or_instance] = constructor
end
else
constructor = function(props)
local clone = assert(class_or_instance:Clone(), "attempt to clone a non-archivable instance")
return apply(clone, props)
end
end end
return if properties return if properties
then ctor(properties) then constructor(properties)
else ctor else constructor
end end
type Instances = { type Instances = {
@ -97,13 +102,6 @@ type function Properties(instance: type?)
return properties return properties
end end
type AnyProps = { [any]: any } type Create = <Name>(Name|keyof<Instances>|"") -> (Properties<index<Instances, Name>>) -> index<Instances, Name>
type Create = (
(Instance) -> (AnyProps) -> Instance
) & (
(string, AnyProps) -> Instance
) & (
<Name>(Name|keyof<Instances>) -> (Properties<index<Instances, Name>>) -> index<Instances, Name>
)
return (create :: any) :: Create return create :: Create

View file

@ -110,4 +110,4 @@ return {
BorderColor3 = Color3.new(0, 0, 0), BorderColor3 = Color3.new(0, 0, 0),
BorderSizePixel = 0 BorderSizePixel = 0
} }
} } :: { [string]: { [string]: unknown} }

View file

@ -1,52 +1,8 @@
type Pseudo = {
Test: number
}
type Instances = {
TextLabel: TextLabel,
TextButton: TextButton,
ImageLabel: ImageLabel,
Pseudo: Pseudo
}
type function Properties(instance: type?)
local properties = types.newtable()
while instance do
for i, v in instance:properties() do
local connector = v.read and v.read.tag == "table" and v.read:readproperty(types.singleton("Connect"))
if connector then
if not connector then continue end
local params = connector:parameters().head
if not params then continue end
local listener = params[2]
if not listener then continue end
properties:setproperty(i, types.optional(listener))
elseif v.write then
properties:setproperty(i, types.optional(types.unionof(
v.write,
types.newfunction({}, { head = { v.write } })
)))
end
end
instance = instance:readparent()
end
properties:setindexer(types.number, types.any)
return properties
end
local function create<Name>(name: Name | keyof<Instances>): (Properties<index<Instances, Name>>) -> index<Instances, Name>
return function()
return "" :: any
end
end
local vide = require "../src/" local vide = require "../src/"
local count = vide.source(0) local count = vide.source(0)
create("TextButton") { -- todo: why is `:: "TextButton"` not necessary?
vide.create("TextButton") {
BackgroundTransparency = 1, BackgroundTransparency = 1,
AnchorPoint = "bad value", -- should error AnchorPoint = "bad value", -- should error
InvalidProperty = true, -- should error InvalidProperty = true, -- should error
@ -65,6 +21,7 @@ create("TextButton") { -- todo: why is `:: "TextButton"` not necessary?
Activated = "bad value", -- should error Activated = "bad value", -- should error
create "TextLabel" {}, vide.create "TextLabel" {},
function() end, function() end,
} }