Luau Recap: May 2021

This month, we have added a new small feature to Luau and spent a lot of time improving our typechecker!

Named function type arguments

We’ve updated Luau syntax to support optional names of arguments inside function types. The syntax follows the same format as regular function argument declarations: (a: number, b: string)

Names can be provided in any place where function type is used, for example:

  • in type aliases:
type MyCallbackType = (cost: number, name: string) -> string
  • for variables:
local cb: (amount: number) -> number
local function foo(cb: (name: string) -> ())

Variadic arguments cannot have an extra name, they are already written as …: number.

These names are used for documentation purposes and we also plan to display them in Roblox Studio auto-complete and type hovers. They do not affect how the typechecking of Luau scripts is performed.

Typechecking improvements

Speaking of typechecking, we’ve implemented many improvements this month:

  • Typechecker will now visit bodies of all member functions, previously it didn’t check methods if the self type was unknown
  • Made improvements to cyclic module import detection and error reporting
  • Fixed incorrect error on modification of table intersection type fields
  • When using an ‘or’ between a nillable type and a value, the resulting type is now inferred to be non-nil
  • We have improved error messages that suggest to use ‘:’ for a method call
  • Fixed order of types in type mismatch error that was sometimes reversed
  • Fixed an issue with table.insert function signature
  • Fixed a bug which caused spurious unknown global errors

We’ve also added new checks to our linter:

  • A new check will report uses of deprecated Roblox APIs
  • Linter will now suggest replacing globals with locals in more cases
  • New warning is generated if array loop starts or ends on index ‘0’, but the array is indexed from ‘1’
  • FormatString lint will now check string patterns for find / match calls via : when object type is known to be a string

We also fixed one of the sources for “Free types leaked into this module’s public interface” error message and we are working to fix the remaining ones. Thank you for your reports!

As usual, typechecking improvements will not break execution of your games even if new errors get reported.

Editor features

We continue to improve our built-in support for auto-complete that will be used in future Roblox Studio updates and will make it easier to implement custom extensions for applications that support Language Server Protocol.

As part of this work we will improve the type information provided by Roblox APIs to match actual arguments and results. You should expect to see functions and events that internally rely on a more precise Instance type like Part but use Instance in the type information right now to gradually switch to using the precise type, e.g. first argument of OnServerEvent will be correctly marked as Player.

Behavior changes

When a relational comparison fails at runtime, the error message now specifies the comparison direction (e.g. attempt to compare nil <= number )

Performance improvements

  • Improved performance of table lookup with an index operator and a literal string: t["name"]
  • Bytecode compilation is now ~5% faster which can improve server startup time for games with lots of scripts

Can you show an example for this? I’m having a hard time understanding this one.

You may want to fix this typo. A typechecker would of been helpful for writing that.


Is this the reason why I have been seeing deprecated auto complete keywords such Workspace, Game in the studio code editor?


Starting to bug me out as I always use auto complete.

1 Like

Thank you for the report, I have fixed the issue :laughing:


Previously, a warning was generated for the following code pattern that is frequently used to setup default values of optional function arguments:

local a: number? = nil – somewhere above or a function argument

local b: number = a or 1 – there was a warning here


I wonder if we can get a userdata type declaration for the datatype returned by newproxy.

Or, if its not too difficult to implement, allowing developers to use the __type metamethod alongside strict typing.

A possible solution which I know slightly breaks the abstraction is a cast like this, from export

export type Cat = {meow: function}

newCat = newproxy(true) :: Cat

Our Studio team is working on a fix for that, we plan to have deprecated items at the end of the list and displayed as Workspace.


Are there plans to simplify typerefinement in cases where a variable can be technically multiple types but will always be of one type to to how my code is structured?
For example in this case whe know that “byte” cannot be nil under any circumstances despite string.byte being technically able to return nil if you input an empty string:


Currently the only ways to silence this warning is current is to do an expensive type check or to declare byte as any to silence the warning but neither of these solutions are great.
Ideally I would want Luau to simply trust me and not give me a warning for doing this:
local byte : number = string.byte("a")


Still not ideal, but there is a cleaner way to do that: local byte = string.byte("a") :: number


That is actually pretty nice. Libraries for storing values via Bytecode to a DataStore should work faster now!

The reason this would be perfect to use in favor of storing data directly through JSON is that it saves even more space in the DataStore, since you are reducing the string by size. Filesystems in native apps like Excel and Outlook use this to store data for projects, and it’s good to know that you can save data like this on Roblox without the cost of performance.

Is there a solution to this warning (in strict mode) apart from using FindFirstChild or type “any”?
I could just ignore this but it is really triggering my OCD.

A more in-depth discussion here:

Is there a solution to this, or is there some feature that will be added in the future which will stop these warnings?

1 Like