Advance Typing
The type
keyword is used for creating an alias for one or more types that already exist.
type Id = number
Fuse has a type semantic type system which means, Because of this verbose type system we should be able to describe anything that can exist in a dynamically typed language like Lua.
For example, we can have an Id
type that can be either a number
or string
.
type Id = number | string
The type
keyword can also be used to describe a compound type based on smaller building blocks.
This type alias describes a type that has both TraitA
and CustomTable
.
type MyType = TraitA & CustomTable
An alias can also contain generic type parameters.
type Api<T> = Backend<DatabaseType, T>
Type erasure
When we assign a value with a known type to an implemented trait type or an ambiguous type we lose some information about that said value’s type.
After assigning a value to such variable we have to cast it back to our desired type, Type casting in Fuse
happens using the as
keyword. A cast operation would only allow a value to be assigned to the cast type but doesn’t provide any checks either in compilation or runtime.
Let’s say we have a value that can either be a number or a string representing a number. Here is one way to describe it.
type AmbigiusType = string | number
let a: AmbigiusType = 1
let b: AmbigiusType = "2"
let mut num1: number = a as number -- compiles and runs
let mut num2: number = b as number -- this would also compiles and run
num1 += 1 -- it will run fine
num2 += 1 -- it will panic in runtime, attempt to add 'string' to 'number'
So we should always value union
types over an ambiguous type with an |
operator, this kind of type needs manual type checking by the developer and compiler some checks while compiling.
Here is the same code using actual manual type checking.
fn add1(n: number | string) -> number
if typeof(n) == "number" then
(n as number) + 1
else
tonumber(n) + 1
end
end
However these checks aren’t enforced by the compiler and are best for describing types from Lua
modules, Here is the same example using union
types.
fn add1(n: NumUntion) -> number
match n when
Numeric(n) then n + 1 end
String(n) then tonumber(n) + 1 end
end
This time we have both compile time and runtime checks in place to ensure that our type is always the thing we are expecting it to be.
- Previous
- Next