Type exclusion and type selections allow developers to have more distinct control over the types which are or are not allowed in a complex environment.
What benefits this provides:
-
Specify what types a function or type template accepts, giving much cleaner and direct typing for complex functions with multiple parameter types.
-
Prevent certain values from being used in generic functions, types, or variables.
type VectorCl = Vector2 | Vector3
type AcceptedTypes = number | CFrame | VectorCl | Color3 | UDim2
local function Lerp<T:AcceptedTypes>(a: T, b: T, c: number): T
return
if typeof(a) == "number" then
a + (b - a) * c
else -- implied that 'T' is one of the other types, aka `AcceptedTypes & (not number)`
a:Lerp(b, c)
end
type SpecialAny = not nil
-- `any & (not nil)` is the same type in this case
local alwaysHasValue: SpecialAny = 2.0
if alwaysHasValue == nil then
-- alwaysHasValue: never
else
-- alwaysHasValue: SpecialAny (not nil)
end
alwaysHasValue = nil -- Type 'not nil' could not be converted into 'nil'
-- Assume Object and ObjectExt are two objects created of the same class, but ObjectExt is a version of the object that does not support this operation
function Class.SpecialOperation<T:(Object & not ObjectExt)>(self: T)
-- ...
end