Most underrated feature - Types

Every programmer have to go through basics, but in Roblox, one thing that is very basic is seen as unimportant or strange, this… those things are types

Many begineers never learn about them (or at least not in a direct way), which is a big mistake, why?

Advantages of using types

  1. They allows others to easily change your code, for instance, settings
  2. They makes your code more redable for you and your co-scripters
  3. They allow you to check if variable belongs to specific type or not
  4. You can create your own custom types

How to use types

Soo, it’s pretty straightforward

local a: number = 5 --/ we add semicolon after variable and we choose from types list
local b: boolean = true
local c: string = "Hello"

We can also use types in tables

local OurList: {string} = {"Lemon", "Orange", "Apple"}

And at the end, we can also use values as types

local b: true = true
local c: "Hello string" = "Hello"

Note: You can’t use numbers here!

Type checking

Soo, apart of setting type to help read our code, we can also check if something belongs to specific type

local a = 5 --/ i didn't added type because it's optional, value still holds number type
if typeof(a) == "number" then
    print("a is a number")
else
    print("a isn't a number")
end

Note: You can’t use type checks with custom types!

Custom types

To create your own custom type, you need to export it, here is how we do it:

export type TableWithEverything = {any} --/ After = symbol we write roblox types or variable types

local OurList: TableWithEverything = {5, 4, true, "Hello", "Lemon", 10}

As you can see, when we press semicolon the code assist suggest TableWithEverything as valid type

Note: We can set our variable’s type to custom one without exporting it, although it’s better and more visually appealing to export it soo it will be highlighted and more understood by others

Additional tips

  1. We can use & or | to create multitype
local BooleanOrNumber: number | boolean

or

export type StringAndTable = string & {}
  1. You shouldn’t use types in middle of scripts, only in function arguments or while working on values that can change (settings variables are the best examples)

  2. You should consider removing comments that explain what value should be like, instead use types

example:

local GunClass = {} --/ OOP class
GunClass.__index = GunClass

vs

local Gun: Class = {}
Gun__index = Gun

Overall, i believe you understood what types are and you will use them in your scripts to improve them

i wish you a nice day, and bye!

9 Likes

As someone who discovered types two days ago, I have found them quite useful, this tutorial has helped expand my understanding on them, thanks!

2 Likes

am i doing this right

13 Likes

local plugin: Plugin = plugin

3 Likes

i already tried it, it doesnt work

3 Likes

It works for me and has for a long time. Are you on the new typechecking studio beta? I’m wondering what might cause it to not work properly here.

3 Likes

honestly i dont care enough to try to figure this out. my solution has been working perfectly well for the past few years and as long my autocomplete is working, im good.

2 Likes

(i need to update those typechecking docs for the new solver, but its still alpha so mehh)

Types are very powerful, esp for autocompletion and keeping code in an otherwise ducktyped language, safe. Use them.

Theres also rumourings that type information may be used to improve the performance of native code, as far as I know this isn’t available just yet but its happening.

3 Likes

I’m glad i have helped you :}

char limit

2 Likes

This is a very surface level description of what you can do with types, but whatever gets people to start using them more. With the addition of native code, typing will start to become essential for optimizations (not to mention the readability and ease of debugging). Good post!

Native code is useable in projects by putting --!native at the top of a script or doing @native on a function definition. And yes, type checking can improve performance in some cases.

I don’t think its underrated since it exist in luau for a long time
there are also other stuff like generics and more which can be found here

3 Likes

The thing is that many new developers don’t use it, youtubers rarely teach about them, but still they are very usefull to improve your code, this is why i made this tutorial

1 Like

yes you are right they don’t exist on most beginner tutorials
also smt that i noted lately

Summary

| and & Arnott the same
| is a called a union and & is called an intersection

| means that 1 of the requirements have to be met/can be 1 of several types while & means that both of the requirements have to be met/value “Must” satisfy several types
if these examples Are not clear the docs should be more straightforward
Type checking - Luau union-types
this works with strict mode

--!strict
type Vector2 = {x: number} | {y: number}

local vec2: Vector2 = {}        -- will give a warning because 1 value atleast should exist
local vec2: Vector2 = {5, 5} -- warning because atleast 1 of them should be assignd to x or y
local vec2: Vector2 = {x = 5} -- no warning because 1 of the requirements is met
local vec2: Vector2 = {0, y=5} -- no warning
local vec2: Vector2 = {y=0, y=5} -- warning u canot have 2 y
etc..

while

--!strict
type Vector2 = {x: number} & {y: number}

local vec2: Vector2 = {} -- warning
local vec2: Vector2 = {5,5} -- warning
local vec2: Vector2 = {x=5, y=8} -- no warning
local vec2: Vector2 = {x=5, x=2} -- warning there should be atleast 1 y
local vec2: Vector2 = {x=5, 5} -- warning there should be atleast 1 y
local vec2: Vector2 = {y=5, z=5}  -- warning variable name canot be z

clearer example

type person = {name :string} & {age : number}

local robloxCharacter1 :person = {name = "Roblox"} -- warning should have age
local robloxCharacter2 :person = {name = "Roblox", age = 20} -- no warning
type person = {name :string} | {age : number}

local robloxCharacter1 :person = {} -- warning none of the conditions is met
local robloxCharacter1 :person = {name = "Roblox"} -- no warning
local robloxCharacter2 :person = {name = "Roblox", age = 20} -- no warning

and you don’t have to use export if its not a module script

2 Likes

Hmmm, i though about it too, but because those operators are used in C#, i didn’t knew that in native lua you can use it too

2 Likes

By the way, is there a way to use typeoff with a custom type?

1 Like

Right now, Luau doesn’t take any notice of type info, it’ll generate the same code regardless of a definition.

What I’m referring to is optimisations made on the expected type of a variable, for example, by default, the statement a + b cant just be optimised as 0 + 1, because it might be a table with an __add metamethod.

If there’s a number type in front of a and b, it can be optimised to just an + at the machine code level.

I was referring to type checking in native code. Roblox specifically says that it can improve performance in some cases.

another unique feature that you can use these for to improve workflow is that when creating a function in, for example, a modulescript, you can tell the script what the passed variables are.

instead of:

function f(x)

do:

function f(x:Part)

that way you can use APIs, i highly recomend it!

I tested it and i don’t think it’s possible sadly

1 Like