Luau Type Checking Beta!

It’s faster than not type checking and obviously runtime type checking.

Now I can become the


for Luau.

(yes I’ve been waiting to use this)

I forgot to attach the benchmark, and it shows my (stupid) assumptions I had beforehand.

And for the code if you want to run it yourself:

local Functions = {}

local function AddTyped(X: number, Y: number) => number
	return X + Y
end

local function AddRuntime(X, Y)
	if type(X) ~= "number" or type(Y) ~= "number" then
		error("bad type boo")
	end

	return X + Y
end

local function AddUntyped(X, Y)
	return X + Y
end

Functions["Luau Types"] = function()
	return AddTyped(5, 10)
end

Functions["Runtime Types"] = function()
	return AddRuntime(5, 10)
end

Functions["No Types"] = function()
	return AddUntyped(5, 10)
end

require(4185109675).new(1, "Title", Functions)

Found an annoying bug. It’s not being redefined twice, as it’s in an if-else block.

Another one, this time with no explanation whatsoever for why it happens. I don’t even call ::GetComponents once in the entire module.

22 Likes

Since this is an invasive change, it might be fitting to have a new extension for typed Lua files, as *.lua is going to make things default to non-typed Lua, basically breaking most existing 3rd party support. I personally suggest *.luau, but whatever it is, it should be officially supported as an option under ‘Save to File’.

As an aside, is there any chance we’ll get an array type built-in? I can see it being annoying to have to continually write type Array<T> = {[number]: T} in scripts.

24 Likes

What’s the motivation behind this? I’m curious, especially since it seems clear that Roblox went with an any type.

7 Likes

Does anything happen when you require another ModuleScript?

3 Likes

Are threads and userdatas supported?

Also, its pretty cool how you can use types to dump out of members of a data type/instance

6 Likes

Types don’t seem to be first-class values :frowning: and I can’t return my newly created type from a module, preventing me from sharing types across scripts.

It’d be a good quality of life improvement to just be able to disable non-strict mode in our games, or make strict mode the default option.

8 Likes

This is awesome to see, really quite game-changing to be honest.
Now there’s no need to do any parameter type checking, which even with a function is a pain.

Will there be support for Roblox datatypes?
Also, the => syntax isn’t really my cuppa tea, if it was -> (like Rust) it’d be much nicer to use.

14 Likes

Also, as many people are mentioning not liking the syntax / thinking it’s too symbol based rather than keyword based: keep in mind that keywords aren’t free. Every keyword they add is an identifier no longer usable. It could end up making scripts harder to port if too many are added. (and yes, adding more would be necessary if you want it to make sense - for example, when specifying the return types of functions)

I do agree that some of the syntax could be more intuitive, but it really isn’t all that bad - I’m fine using it personally :slightly_smiling_face:

6 Likes

Are we getting a function primitive in the future? Currently there’s no way to:

local function foo(function: func) => void
    func()
end

Also, non-returning functions should have return type void for those C programmers out there :stuck_out_tongue:

14 Likes

Another question I have is if type unions and intersections (i.e. set operations) will be supported.

Finally, do we expect to see type predicates (i.e. function that verify or assert a type) on the roadmap?

Both of these features are really powerful, and something I’d love to see from TypeScript moved into this type system.

8 Likes

Do we have to write it that way or can we write it that way?

5 Likes

I believe in the Luau progress thread Zeuxcg said that at the moment types are automatically exported from modules:

5 Likes

Piggybacking off your reply; a thought prompted by your type predicates idea, does typeof support custom type aliases?

4 Likes

You should be able to export types from ModuleScripts by doing this:

Foo ModuleScript:

type Bar = ...

return {}

script:

local Foo = require(script.Parent.Foo)

local value: Foo.Bar = 2

You’re right that they aren’t first class values, they exist in a separate namespace from normal variables.

14 Likes

I think we might not support tracing requires generically enough for this to work in games though… So this might not work yet in the beta.

6 Likes

Basically because any allows you to get around the type checker easily. Easy footgun.

Also because it was much simpler to handle compilation to Lua with no any. :stuck_out_tongue:

Since - for example - adding strings in lua and adding numbers in lua have completely different syntaxes, for example.

Speaking of which…

function add(x: number, y: number)
    return x + y
end

local z = add(10, "i want to break this" as any);

This literally will error because you can’t add a string using a +.


And if you think that nobody will do this, they will. This sort of stuff happened before we banned any.

7 Likes

I suspect since typeof() is actually a function, supporting custom types here would be a bad idea. Roblox will probably have to declare another type checking function, or maybe just accept that this breaks some stuff (I don’t even know if types are readable on run time).

5 Likes

Am I missing something crucial here?

workspace.ChildAdded:Connect(function(Object: Instance) => nil

end) -- Perfectly fine

However,

local x : Instance = workspace
x.ChildAdded:Connect(function(Object: Instance) => nil

end) -- W00 Argument count mismatch. Function takes 2 arguments but you passed 1

I’m guessing only primitives are currently fully supported?

10 Likes

We don’t actually optimize based on type information (yet) so the delta between types & no types you’re seeing must be statistical noise.

We will though. Just not yet.

12 Likes

Yeah, would need Rojo to support it as well as an extension to highlight .luau files. (Possibly in the future roblox could also release a language server for rojo users so we can get intellisense etc?)

8 Likes