Luau: narrowing & inference is fundamentally borked and provides a worse developer experience

type AModelWithAnInterface = Model & { foo: boolean }
type InterfaceWithAModel = { foo: boolean } & Model;
local x: AModelWithAnInterface = 0 :: any;
local y: InterfaceWithAModel = 0 :: any

print(x.foo) -- `x` doesn't have foo or whatever
print(y.foo) -- works (for some reason?
  • metatables still are broken, __call will completely kill your lints and will most likely make your type function uninhabited
  • newproxy returns ‘any’ for some reason instead of some metatable type
  • intersecting inside the second argument of setmetatable makes the type function uninhabited
    • but intersecting two setmetatable type functions works as how the former would expect. how does that make sense
  • unknown types get automatically narrowed during use when passed to a field that has a type (e.g. in a dictionary)
  • unions are regarded as wholly invalid when one side of the union operand is invalid despite the other side being totally valid
  • whatever the hell this is:
    • RobloxStudioBeta_N4s8BbLNHr
  • unclosed statements break inference/narrowing/intellisense which can make writing conditions the worst experience known to man
  • type guards that do not explicitly check against nil end up refining the type as ~(false) rather than ~(false) & ~(nil) - you see this a LOT when using {[string]: any}:
  • tables that are typed against {[...]: any} end up making all keyed entries in said table ‘any’
  • it legitimately halluincates my metatables away despite the intellisense doing otherwise:
  • i literally don’t even know anymore man (warning: ultra compressed to be able to upload this to here)
  • what
  • anonymous autocomplete snippets literally include “… X more” in it
  • you guys forgot to do tabletype:metatable(...) for assert. as it is, any metatable you pass through as the first parameter will kill the metatable.
  • this literally does not make sense

Expected behavior

these things will not occur because strict typing was actually tested in this ideal universe before being released :smiling_face_with_three_hearts:

7 Likes

That’s unfortunately because intersections on extern types can’t really work right now due to the lack of “shape types,” the latter appearing to work is a bug that has not been fixed to avoid breaking legitimate use cases :frowning:

The single-argument constructor of NumberSequence appears to take { NumberSequenceKeypoint }, but the last value in the table literal is NumberSequenceKeypoint | nil. The type error seems correct to me?

The New Type Solver was actually under opt-in Beta for over a year before general release:

2 Likes

The single-argument constructor of NumberSequence appears to take { NumberSequenceKeypoint }, but the last value in the table literal is NumberSequenceKeypoint | nil. The type error seems correct to me?

it does not matter and it should not matter if the type if the last entry of the array literal is nullish because nil only matters if it’s a hole in an array. why should i have to make an entirely new branch for an entry that represents a potential end?

The New Type Solver was actually under opt-in Beta for over a year before general release:

opt-in beta ~= testing your changes before you push them. some of these are legitimately bewildering that they even made it past review. and honestly, that gives the feel of “it’s the community’s fault for not reporting the bugs” when there should be ongoing testing internally. i just don’t get it

This bug reports isn’t actionable. It’s something like 16 bug reports in one. You should limit yourself to one bug per report.

3 Likes

I used to use this feature as part of the old Typechecker (e.g. Model & { Humanoid : Humanoid }) for character models that had been confirmed to have loaded properly and manually-typed GUI templates.

I figured it was just an unintentional bug with the old Typechecker that all of us were misusing without realising for ages. While there’s no workaround directly for this, the closest thing you can do for things like templated/cloned objects that get used as the basis for object transformations is to just do typeof(locationToMyTemplate) , such as typeof(script.LeaderboardPlayerCardTemplate) and have the typechecker infer the structure from there.

Annoyingly, only the engine itself can generate these uniquely structured types while we can’t manually define them ourselves. (I can’t get either model example to work, because it doesn’t seem to like mixing a ROBLOX Type with userdata types, or a table of ROBLOX types).

1 Like

I’d love some better ideas. I feel like if I post every bug report individually I’d get sent straight to the can for spamming up the bug reports @_@

If they’re legitimate reports, you won’t. Good faith efforts at reporting problems won’t get you in trouble. As-is, this bug reports has too much going on and I’d be surprised if anyone at Roblox actually acted upon it. Every bug reports corresponds to one ticket internally, and nobody is going to take on a ticket with 16 different problems in it.

Some of them aren’t actually Luau problems and I believe they’re bugs with the Studio assistant, which also complicates things. That’s not really our problem as users though; someone at Roblox will fix it if a bug is reported to the wrong team as long as you get close enough.

2 Likes

Thanks for the report! As Dekkonot mentioned, this ticket is pretty inactionable as-is because it combines a large number of disconnected bugs. We’d love to be able to fix these problems, but we need them to be submitted separately in order to be able to reasonably track the work involved, and ideally each report would have a reproduction attached, rather than just a video or screenshot, to allow us to reproduce the issue on our end when going to fix it. Since this individual ticket itself cannot be addressed, I’m going to close it out, but please do report bugs individually (and check for existing reports that match the description, you can reply and include additional reproductions there!). Even if you’re reporting a lot of issues, as long as you’re putting the effort in to describe the reproductions, it will make resolving them much smoother.

these things will not occur because strict typing was actually tested in this ideal universe before being released :smiling_face_with_three_hearts:

As an aside, we are only humans (and a fairly small number of them at that!) building software. I understand experiencing bugs is frustrating, but we do actually test the type system, including the beta but also extensively on our own. We’ve been working hard for years to increase the robustness of the test suite we have available, but the type inference engine for Luau is a very complicated piece of technology and the ways in which all of our users try to use it vary greatly. We’ll keep doing our best to increase test coverage, and, of course, we will always be working hard to improve the product, but the sass here is just not necessary.

3 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.