Luau Type Checking Beta!

Instances do not have a Position though, so that type error is correct. You would need to typecheck it as a BasePart (or whatever you are trying to have it be that has a Position property).

1 Like

In this case we may end up throwing our own error if the instance isn’t a BasePart, and type checking values ourselves using IsA can kill performance in heavily used code. If an instance is assumed by the developer to have a compatible property, then should attempting to access an invalid instance during run time be what errors instead? The warning may still be justified though; Perhaps a could be defined as a union of the types Vector3 and BasePart?

I would generally recommend just redesigning the script so that hacky type checks aren’t needed, but I’ve come across rare scenarios where it’s more performant to reuse a table’s fields for values of different types.

3 Likes

Is there a way to indicate that a function returns a table? The following code warns Unknown symbol 'table':
image

2 Likes

You just place {}.

1 Like

I found a bug with strict mode:

--!strict

local RunService = game:GetService("RunService")
local onHeartbeat: RBXScriptConnection = RunService.Heartbeat:Connect(function(delta: number)
      --> Error: Argument count mismatch. Function takes 2 arguments,
      -->           but you passed 1
end)

Do i not need to specify what the table will be containing?

You don’t have to, but you can.

1 Like

I’d assume specifying {} as the return type means an empty table. Returning an unstructured table kinda defeats the purpose of using this.

If you want to specify the return value to be something like “an array of T” where T is some type (e.g. Instance), you can specify the return type as: { [number]: Instance }.

If you want to specify a dictionary that maps strings to Instance, { [string]: Instance }.

2 Likes


What is free19365-1-0? module.NaN is 0/0 by the way.

local Bezier: {
    Points = {[number]: Vector3}
} = {Points = {}}

This should work I believe.

1 Like

Based on what I heard that garbage naming is a side effect of how types are generated. Also, do you mean module.NaN is a function that returns NaN, or its just NaN? If its the latter the error would make sense. It can’t convert NaN (a number) to a function that returns type free19365-1-0 (Which seems to be an internal type thats being inferred from some context?)

Edit: It appears that free types are generated at runtime and assigned to any invalid call (it cant infer the type since there is no function to reference)

1 Like

I think you would have to use this

type Verts = {[number]: Vector3}

function PartUtil:GetVertices(Part: BasePart) => Verts
    return verts
end

Alternatively you dont need to specify that type but it makes it easier later on to just use

local result: Verts = PartUtil:GetVertices(myPart)

Also another issue:

Or you could just do {[any]:any}. I don’t believe it will view it as empty though as that defeats the whole purpose of a table.

I have since discovered what the gibberish types are caused by. They are invalid types, but they can technically be replaced with any and it’d still make sense.

Also, does anyone know the replacement for the as keyword? I can’t find anything about it changing in updates and currently it causes a syntax error.

The as keyword is disabled. You can already annotate with x: datatype so I don’t see the point of as. But maybe that is just me

2 Likes

Are there any plans to cover varargs with type annotations? I’ve ran into a case where I’m adding types to a function that uses vararg and it’s holding me back.

10 Likes

Would be great if this could be addressed. I have an entire library that I can’t properly annotate because most of the functions involve variable arguments.

https://github.com/Anaminus/roblox-library/blob/master/modules/Sync/Sync.lua

2 Likes

Please, please, fix the following warning from appearing:

local scope1 = {}
local scope2 = {}
do
	function scope1.foo()
		print("foo")
		scope2.bar()
	end
end
do 
	function scope2.bar()
		print("bar")
	end
end 
scope1.foo()

W000:(7,3) Key "bar" not found in scope2
image
The code works, the warning is a fluke that didn’t used to occur but now I’m getting false warnings all over my code where there definitely shouldn’t be, and it’s distracting me from actual warnings in my code.
I actually have to disable the little tab that shows the list of all the warnings in my code because nearly all of them are false warnings of this type.
While I love the new update, this plethora of false warnings is distracting me from true warnings making it harder for me to diagnose mistakes in my code.

I wonder if one of the future plans is function overloading. This would make it far more efficient at runtime to skip type checking when we make class methods or functions. Of course this isn’t possible with regular lua but since typing is being added and the VM is being adjusted, it could be a possibility.
With regular functions, you can probably just rename them but that also means they are less flexible. As for things like metamethods, it will be a lot better while making it easier to customize.

C++ example with regular functions:

int integerDivide(int a, int b) { return a / b; }
double integerDivide(double a, double b) { return floor(a / b); }
cout << integerDivide(10, 3) << endl; // 3
cout << integerDivide(25.5, 2.2) << endl; // 12.0

And in a class:

// Quat + Quat
Quat operator+(Quat other) {
  return Quat(X + other.X, Y + other.Y, Z + other.Z, W + other.W);
}
// Quat + double
Quat operator+(double other) {
  return Quat(X + other, Y + other, Z + other, W + other);
}