type test = {
number: number,
string: string,
Instance: Instance
}
function something<R>(a: keyof<test>&R): index<test,R> [...] end
But this has issues because the &R ruins the typechecking for input but gives correct output.
I basically want this something function to work like Instance.new. How do I do this?
not sure what the provided code is… but check out typeof() which returns the type of the passed object as a string. ex. typeof("hi") would return "string"
ohhh ic what you mean. why can’t you simply use strings? if you ever need to compare anything, you can just use typeof. anyways, i dont believe this is even possible
I don’t think you understand my question.
Strings obviously work, but i’m asking if there is a way, with the current type system, to make a function signature that takes a string literal and returns the type with the name of the literal
Because it’s annoying to have to annotate every variable’s type if you want to have a function that can generate multiple types depending on the parameter, like Instance.new. With Instance.new(“Part”), you don’t have to do local p: Part = Instance.new("Part") just to get all of the script autocomplete magic. Point is, the function needs to guess the return type from a given string type name.
ok so after some research i found that lua doesnt support passing a list of types (like a type[] or an array of types) to create a union type automatically. unfortunately, you have to explicitly type in the union when defining function parameters or variables. this aligns with my previous statements.
edit: i think some languages actually do tho. sadly, not lua
No, you don’t. That’s the point of keyof! it creates a union for you of keys to a type!
if you want a union of values, index is the way.
Oh also that’s the point of the test type, to let keyof and index work their magic. The issue is my implementation of this aint working. I need help with it.
I will refer you to this thread, it is a pearl for working with the new solver. It is hard to find information about how to use the new solver due to how new (and still incomplete) it is
What you will need is probably definitely type functions, however, I do not know how to apply them to a function in such a way that the return type depends on the input type. I was however able to apply the type function to a simple variable, depending on the string
--!strict
type SomeTypeAlias = {
a : number,
b : number,
}
type function TypeFunction(Type : type)
if Type:value() == "Test1" then
return types.string
elseif Type:value() == "Test2" then
return SomeTypeAlias
else
error("Invalid type")
end
end
local a : TypeFunction<"Test2">
(Note that type functions can now return type aliases, which wasn’t the case at the time of this reply)
local function something(a: "number"): number
return a
end
local function something(a: "string"): string
return a
end
local function something(a: "Part"): Part
return a
end
local g = something("Part")
g.Pos
That’s not how it works, luau doesn’t support function overloading like java or other languages. What is happening here is the something function is being overwritten every time you redefine it, and the last time you define it, is the one that returns Part, which is why you are getting autocomplete for position
However, there is this section that talks about a way to do function overloading for types
I don’t think the “easy” way to do it works, because it only works for different types, and not different values of types (aka specific strings), but it could be possible to make a type function that constructs an “overloaded function” using type intersections, and creating specific strings types using types.singleton("WhateverTheStringIs")
I cannot figure out how to make this work because the problem is more or less with generics than anything else. In my original example, the generic R ruins the input union to make the output work. My goal is to make the input union correctly work AND output value.
The problem is with how Luau infers string literals as the type string, not as a string literal type. You’re annotations actually do work, but only when you explicitly cast the arguments.
-- a is string, index<test, string> is error
local x = something("number")
-- a is "number", index<test, "number"> is number
local y = something("number" :: "number")
Even with generic constraints, this won’t be possible until the inference behavior changes.
yea, my issue though is because intersectioning R with the keyof ruins input type inference. I want to be able to infer input while also being able to infer output