t
t is a runtime type checker for Roblox Luau. It is a fork of
osyrisrblx/t published as kashtheking/t, with the same
API plus checks for newer Roblox types (buffer, Content, Font, FloatCurveKey, ...).
Checks
Everything in t is built from checks. A check is a function with the signature
(value: any) -> (boolean, string?): it returns true when the value is acceptable, or
false followed by a human-readable message explaining what was wrong. Members of t come
in two flavours:
-
Plain checks that you call directly:
t.string,t.number,t.boolean,t.table,t.Instance,t.Vector3,t.CFrame,t.any,t.integer,t.nan,t.numberPositive, ... -
Check constructors that take arguments and return a new check, so you compose them:
t.optional(t.string),t.array(t.number),t.numberMin(0),t.literal("a", "b"),t.interface({ ... }),t.tuple(...),t.instanceIsA("BasePart").
Because a failing check returns false, message, assert(check(value)) raises that message
as the error, which is the idiomatic way to guard arguments.
local t = require(path.to.t)
local ok, err = t.number(5) --> true
ok, err = t.number("5") --> false, "number expected, got string"
-- Build checks once, at module level, and reuse them.
local IsSaveData = t.interface({
Level = t.numberMin(1),
Coins = t.integer,
Inventory = t.array(t.string),
Nickname = t.optional(t.string),
Team = t.literal("Red", "Blue"),
})
local checkSave = t.tuple(t.instanceIsA("Player"), IsSaveData)
local function savePlayer(player, data)
assert(checkSave(player, data))
-- ...
end
-- Or let t generate the guard for you:
local savePlayerStrict = t.wrap(savePlayer, checkSave)
local assertSave = t.strict(checkSave) -- assertSave(player, data) errors on bad input
Type checks
The plain type checks are created with t.typeof (or t.type for userdata and vector)
and simply compare the value's type name. Lua primitives: t.boolean, t.buffer, t.thread,
t.callback (alias t["function"]), t.none (alias t["nil"]), t.string, t.table,
t.userdata, t.vector, plus t.number (which rejects NaN) and t.nan. Roblox data types:
t.Axes, t.BrickColor, t.CatalogSearchParams, t.CFrame, t.Content, t.Color3,
t.ColorSequence, t.ColorSequenceKeypoint, t.DateTime, t.DockWidgetPluginGuiInfo,
t.Enum, t.EnumItem, t.Enums, t.Faces, t.FloatCurveKey, t.Font, t.Instance,
t.NumberRange, t.NumberSequence, t.NumberSequenceKeypoint, t.OverlapParams,
t.PathWaypoint, t.PhysicalProperties, t.Random, t.Ray, t.RaycastParams,
t.RaycastResult, t.RBXScriptConnection, t.RBXScriptSignal, t.Rect, t.Region3,
t.Region3int16, t.TweenInfo, t.UDim, t.UDim2, t.Vector2, t.Vector2int16,
t.Vector3, t.Vector3int16. Each is also listed individually below.
Aliases
t.some = t.union, t.every = t.intersection, t.instance = t.instanceOf,
t["function"] = t.callback, t["nil"] = t.none, and the deprecated t.exactly =
t.literal.
Credits: t was created by Osyris (osyrisrblx/t, MIT). This build is his library published to Wally as kashtheking/t with checks for newer Roblox data types added by KashTheKing.
Installation and guide: t package page.
Types
Check
type Check = (value: any) → (boolean,string?)
A type check. Returns true if value is acceptable, otherwise false and a message that
describes the problem. Every plain check in t has this signature and every check constructor
returns one, so checks can be nested freely (t.array(t.optional(t.number))).
Functions
type
t.type(typeName: string--
The name type() must return, e.g. "userdata", "vector", "string".
) → Check--
Fails with "<typeName> expected, got <actual>".
Returns a check that passes when Lua's type(value) equals typeName. Prefer t.typeof for
anything but the raw Lua categories, because type reports every Roblox data type as
"userdata" (and Vector3 as "vector").
local isUserdata = t.type("userdata")
print(isUserdata(CFrame.new())) --> true
typeof
t.typeof(typeName: string--
The name typeof() must return, e.g. "Vector3", "Instance", "EnumItem".
) → Check--
Fails with "<typeName> expected, got <actual>".
Returns a check that passes when Roblox's typeof(value) equals typeName. This is how all
the built-in type checks (t.string, t.Vector3, t.Instance, ...) are made, so you only
need it for a type that has no ready-made check.
local isSharedTable = t.typeof("SharedTable")
any
t.any(value: any--
The value to check.
) → (boolean,--
true unless value is nil.
string?--
"any expected, got nil" on failure.
)
Passes for every value except nil. Use it for interface fields that must be present but may
hold anything.
boolean
t.boolean(value: any--
The value to check.
) → (boolean,--
Whether the value has the expected type.
string?--
"<type> expected, got <actual>" on failure.
)Passes when typeof(value) == "boolean".
buffer
t.buffer(value: any--
The value to check.
) → (boolean,--
Whether the value has the expected type.
string?--
"<type> expected, got <actual>" on failure.
)Passes when the value is a Luau buffer.
thread
t.thread(value: any--
The value to check.
) → (boolean,--
Whether the value has the expected type.
string?--
"<type> expected, got <actual>" on failure.
)Passes when the value is a coroutine (thread).
callback
t.callback(value: any--
The value to check.
) → (boolean,--
Whether the value has the expected type.
string?--
"<type> expected, got <actual>" on failure.
)Passes when the value is a function. Also available as t["function"]. Every check constructor in t uses this internally to assert that the checks it receives are functions.
none
t.none(value: any--
The value to check.
) → (boolean,--
Whether the value has the expected type.
string?--
"<type> expected, got <actual>" on failure.
)Passes only for nil. Also available as t["nil"]. Useful inside t.union or t.tuple when a position must be empty.
string
t.string(value: any--
The value to check.
) → (boolean,--
Whether the value has the expected type.
string?--
"<type> expected, got <actual>" on failure.
)Passes when the value is a string.
table
t.table(value: any--
The value to check.
) → (boolean,--
Whether the value has the expected type.
string?--
"<type> expected, got <actual>" on failure.
)Passes when the value is a table (any table, including arrays and objects with metatables). Use t.array, t.map, t.set or t.interface to check the contents as well.
userdata
t.userdata(value: any--
The value to check.
) → (boolean,--
Whether the value has the expected type.
string?--
"<type> expected, got <actual>" on failure.
)Passes when Lua's type(value) is "userdata", which is true for almost every Roblox data type (CFrame, Instance, Color3, ...) but not for Vector3, which is a native vector.
vector
t.vector(value: any--
The value to check.
) → (boolean,--
Whether the value has the expected type.
string?--
"<type> expected, got <actual>" on failure.
)Passes when Lua's type(value) is "vector", i.e. the value is a Vector3 (Luau stores Vector3 as a native vector). Equivalent in practice to t.Vector3.
number
t.number(value: any--
The value to check.
) → (boolean,--
true for any non-NaN number.
string?--
"number expected, got <type>" or "unexpected NaN value" on failure.
)
Passes when the value is a number and is not NaN. Every numeric check in t
(t.integer, t.numberMin, t.numberConstrained, ...) is built on this, so NaN never
slips through them either. Use t.nan if you specifically want to accept NaN.
print(t.number(1.5)) --> true
print(t.number(0/0)) --> false, "unexpected NaN value"
print(t.number("1")) --> false, "number expected, got string"
nan
t.nan(value: any--
The value to check.
) → (boolean,--
true only for NaN.
string?--
The failure message.
)
Passes only when the value is a number that is NaN (value ~= value). Non-numbers fail with
a type message; ordinary numbers fail with "unexpected non-NaN value".
Axes
t.Axes(value: any--
The value to check.
) → (boolean,--
Whether the value is a Axes.
string?--
"Axes expected, got <actual>" on failure.
)Passes when typeof(value) == "Axes".
BrickColor
t.BrickColor(value: any--
The value to check.
) → (boolean,--
Whether the value is a BrickColor.
string?--
"BrickColor expected, got <actual>" on failure.
)Passes when typeof(value) == "BrickColor".
CatalogSearchParams
t.CatalogSearchParams(value: any--
The value to check.
) → (boolean,--
Whether the value is a CatalogSearchParams.
string?--
"CatalogSearchParams expected, got <actual>" on failure.
)Passes when typeof(value) == "CatalogSearchParams".
CFrame
t.CFrame(value: any--
The value to check.
) → (boolean,--
Whether the value is a CFrame.
string?--
"CFrame expected, got <actual>" on failure.
)Passes when typeof(value) == "CFrame".
Content
t.Content(value: any--
The value to check.
) → (boolean,--
Whether the value is a Content.
string?--
"Content expected, got <actual>" on failure.
)Passes when typeof(value) == "Content" (the Content data type used by asset properties).
Color3
t.Color3(value: any--
The value to check.
) → (boolean,--
Whether the value is a Color3.
string?--
"Color3 expected, got <actual>" on failure.
)Passes when typeof(value) == "Color3".
ColorSequence
t.ColorSequence(value: any--
The value to check.
) → (boolean,--
Whether the value is a ColorSequence.
string?--
"ColorSequence expected, got <actual>" on failure.
)Passes when typeof(value) == "ColorSequence".
ColorSequenceKeypoint
t.ColorSequenceKeypoint(value: any--
The value to check.
) → (boolean,--
Whether the value is a ColorSequenceKeypoint.
string?--
"ColorSequenceKeypoint expected, got <actual>" on failure.
)Passes when typeof(value) == "ColorSequenceKeypoint".
DateTime
t.DateTime(value: any--
The value to check.
) → (boolean,--
Whether the value is a DateTime.
string?--
"DateTime expected, got <actual>" on failure.
)Passes when typeof(value) == "DateTime".
DockWidgetPluginGuiInfo
t.DockWidgetPluginGuiInfo(value: any--
The value to check.
) → (boolean,--
Whether the value is a DockWidgetPluginGuiInfo.
string?--
"DockWidgetPluginGuiInfo expected, got <actual>" on failure.
)Passes when typeof(value) == "DockWidgetPluginGuiInfo".
Enum
t.Enum(value: any--
The value to check.
) → (boolean,--
Whether the value is a Enum.
string?--
"Enum expected, got <actual>" on failure.
)Passes when typeof(value) == "Enum" (the enum type, e.g. Enum.Material, not one of its items; see t.EnumItem and t.enum).
EnumItem
t.EnumItem(value: any--
The value to check.
) → (boolean,--
Whether the value is a EnumItem.
string?--
"EnumItem expected, got <actual>" on failure.
)Passes when typeof(value) == "EnumItem" (an item such as Enum.Material.Plastic; use t.enum to also require a specific enum).
Enums
t.Enums(value: any--
The value to check.
) → (boolean,--
Whether the value is a Enums.
string?--
"Enums expected, got <actual>" on failure.
)Passes when typeof(value) == "Enums" (the global Enum table itself).
Faces
t.Faces(value: any--
The value to check.
) → (boolean,--
Whether the value is a Faces.
string?--
"Faces expected, got <actual>" on failure.
)Passes when typeof(value) == "Faces".
FloatCurveKey
t.FloatCurveKey(value: any--
The value to check.
) → (boolean,--
Whether the value is a FloatCurveKey.
string?--
"FloatCurveKey expected, got <actual>" on failure.
)Passes when typeof(value) == "FloatCurveKey".
Font
t.Font(value: any--
The value to check.
) → (boolean,--
Whether the value is a Font.
string?--
"Font expected, got <actual>" on failure.
)Passes when typeof(value) == "Font".
Instance
t.Instance(value: any--
The value to check.
) → (boolean,--
Whether the value is a Instance.
string?--
"Instance expected, got <actual>" on failure.
)Passes when typeof(value) == "Instance" (any Instance; use t.instanceOf, t.instanceIsA or t.children to be more specific).
NumberRange
t.NumberRange(value: any--
The value to check.
) → (boolean,--
Whether the value is a NumberRange.
string?--
"NumberRange expected, got <actual>" on failure.
)Passes when typeof(value) == "NumberRange".
NumberSequence
t.NumberSequence(value: any--
The value to check.
) → (boolean,--
Whether the value is a NumberSequence.
string?--
"NumberSequence expected, got <actual>" on failure.
)Passes when typeof(value) == "NumberSequence".
NumberSequenceKeypoint
t.NumberSequenceKeypoint(value: any--
The value to check.
) → (boolean,--
Whether the value is a NumberSequenceKeypoint.
string?--
"NumberSequenceKeypoint expected, got <actual>" on failure.
)Passes when typeof(value) == "NumberSequenceKeypoint".
OverlapParams
t.OverlapParams(value: any--
The value to check.
) → (boolean,--
Whether the value is a OverlapParams.
string?--
"OverlapParams expected, got <actual>" on failure.
)Passes when typeof(value) == "OverlapParams".
PathWaypoint
t.PathWaypoint(value: any--
The value to check.
) → (boolean,--
Whether the value is a PathWaypoint.
string?--
"PathWaypoint expected, got <actual>" on failure.
)Passes when typeof(value) == "PathWaypoint".
PhysicalProperties
t.PhysicalProperties(value: any--
The value to check.
) → (boolean,--
Whether the value is a PhysicalProperties.
string?--
"PhysicalProperties expected, got <actual>" on failure.
)Passes when typeof(value) == "PhysicalProperties".
Random
t.Random(value: any--
The value to check.
) → (boolean,--
Whether the value is a Random.
string?--
"Random expected, got <actual>" on failure.
)Passes when typeof(value) == "Random" (a Random object from Random.new).
Ray
t.Ray(value: any--
The value to check.
) → (boolean,--
Whether the value is a Ray.
string?--
"Ray expected, got <actual>" on failure.
)Passes when typeof(value) == "Ray".
RaycastParams
t.RaycastParams(value: any--
The value to check.
) → (boolean,--
Whether the value is a RaycastParams.
string?--
"RaycastParams expected, got <actual>" on failure.
)Passes when typeof(value) == "RaycastParams".
RaycastResult
t.RaycastResult(value: any--
The value to check.
) → (boolean,--
Whether the value is a RaycastResult.
string?--
"RaycastResult expected, got <actual>" on failure.
)Passes when typeof(value) == "RaycastResult".
RBXScriptConnection
t.RBXScriptConnection(value: any--
The value to check.
) → (boolean,--
Whether the value is a RBXScriptConnection.
string?--
"RBXScriptConnection expected, got <actual>" on failure.
)Passes when typeof(value) == "RBXScriptConnection".
RBXScriptSignal
t.RBXScriptSignal(value: any--
The value to check.
) → (boolean,--
Whether the value is a RBXScriptSignal.
string?--
"RBXScriptSignal expected, got <actual>" on failure.
)Passes when typeof(value) == "RBXScriptSignal".
Rect
t.Rect(value: any--
The value to check.
) → (boolean,--
Whether the value is a Rect.
string?--
"Rect expected, got <actual>" on failure.
)Passes when typeof(value) == "Rect".
Region3
t.Region3(value: any--
The value to check.
) → (boolean,--
Whether the value is a Region3.
string?--
"Region3 expected, got <actual>" on failure.
)Passes when typeof(value) == "Region3".
Region3int16
t.Region3int16(value: any--
The value to check.
) → (boolean,--
Whether the value is a Region3int16.
string?--
"Region3int16 expected, got <actual>" on failure.
)Passes when typeof(value) == "Region3int16".
TweenInfo
t.TweenInfo(value: any--
The value to check.
) → (boolean,--
Whether the value is a TweenInfo.
string?--
"TweenInfo expected, got <actual>" on failure.
)Passes when typeof(value) == "TweenInfo".
UDim
t.UDim(value: any--
The value to check.
) → (boolean,--
Whether the value is a UDim.
string?--
"UDim expected, got <actual>" on failure.
)Passes when typeof(value) == "UDim".
UDim2
t.UDim2(value: any--
The value to check.
) → (boolean,--
Whether the value is a UDim2.
string?--
"UDim2 expected, got <actual>" on failure.
)Passes when typeof(value) == "UDim2".
Vector2
t.Vector2(value: any--
The value to check.
) → (boolean,--
Whether the value is a Vector2.
string?--
"Vector2 expected, got <actual>" on failure.
)Passes when typeof(value) == "Vector2".
Vector2int16
t.Vector2int16(value: any--
The value to check.
) → (boolean,--
Whether the value is a Vector2int16.
string?--
"Vector2int16 expected, got <actual>" on failure.
)Passes when typeof(value) == "Vector2int16".
Vector3
t.Vector3(value: any--
The value to check.
) → (boolean,--
Whether the value is a Vector3.
string?--
"Vector3 expected, got <actual>" on failure.
)Passes when typeof(value) == "Vector3" (the same as t.vector).
Vector3int16
t.Vector3int16(value: any--
The value to check.
) → (boolean,--
Whether the value is a Vector3int16.
string?--
"Vector3int16 expected, got <actual>" on failure.
)Passes when typeof(value) == "Vector3int16".
literalList
t.literalList(literals: {any}--
The allowed values.
) → Check--
Passes when the value equals one of the literals.
Returns a check that passes when the value is equal (==) to any entry of the literals
array. Same as t.literal with several arguments, but takes a table, which is convenient
when the allowed values already live in a list. The failure message is the generic
"bad type for literal list".
local isDirection = t.literalList({ "North", "East", "South", "West" })
literal
t.literal(...: any--
One or more values the checked value may equal.
) → Check--
Passes when the value equals one of the literals.
Returns a check for one or more exact values. With a single argument the check passes only
when value == literal and fails with "expected <literal>, got <value>". With several
arguments it returns a t.unionList of one-literal checks (so the message becomes
"bad type for union"). Deprecated alias: t.exactly.
local isTrue = t.literal(true)
local isTeam = t.literal("Red", "Blue")
print(isTeam("Green")) --> false, "bad type for union"
keyOf
t.keyOf(keyTable: {[any]: any}--
The table whose keys are the allowed values.
) → Check--
Passes when the value equals one of the keys.
Returns a check that passes when the value is one of the keys of keyTable, built as
t.literal(key1, key2, ...). Handy for validating an option name against a dictionary of
handlers. The key set is captured when keyOf is called; later changes to the table are not
seen.
local handlers = { Jump = jump, Crouch = crouch }
local isAction = t.keyOf(handlers)
print(isAction("Jump")) --> true
print(isAction("Fly")) --> false
valueOf
t.valueOf(valueTable: {[any]: any}--
The table whose values are the allowed values.
) → Check--
Passes when the value equals one of the table's values.
Returns a check that passes when the value is one of the values of valueTable, built as
t.literal(value1, value2, ...). Useful with enum-like tables of constants. The value set is
captured when valueOf is called.
local Rarity = { Common = 1, Rare = 2, Epic = 3 }
local isRarity = t.valueOf(Rarity)
print(isRarity(2)) --> true
integer
t.integer(value: any--
The value to check.
) → (boolean,--
Whether the value is an integer.
string?--
The failure message.
)
Passes when the value is a non-NaN number with no fractional part (value % 1 == 0).
math.huge passes; 1.5 fails with "integer expected, got 1.5".
numberMin
t.numberMin(min: number--
The smallest accepted value.
) → Check--
Fails with "number >= <min> expected, got <value>".
Returns a check that passes for numbers where value >= min (inclusive). Non-numbers and NaN
fail with the t.number message.
local isNonNegative = t.numberMin(0)
numberMax
t.numberMax(max: number--
The largest accepted value.
) → Check--
Fails with "number <= <max> expected, got <value>".
Returns a check that passes for numbers where value <= max (inclusive).
numberMinExclusive
t.numberMinExclusive(min: number--
The bound; the value itself is not accepted.
) → Check--
Fails with "number > <min> expected, got <value>".
Returns a check that passes for numbers where value > min (exclusive).
numberMaxExclusive
t.numberMaxExclusive(max: number--
The bound; the value itself is not accepted.
) → Check--
Fails with "number < <max> expected, got <value>".
Returns a check that passes for numbers where value < max (exclusive).
numberPositive
t.numberPositive(value: any--
The value to check.
) → (boolean,--
Whether the value is a number > 0.
string?--
The failure message.
)
Passes for numbers strictly greater than zero; equivalent to t.numberMinExclusive(0). Zero
fails. This is a ready-made check, not a constructor: call it with the value directly.
numberNegative
t.numberNegative(value: any--
The value to check.
) → (boolean,--
Whether the value is a number < 0.
string?--
The failure message.
)
Passes for numbers strictly less than zero; equivalent to t.numberMaxExclusive(0). Zero
fails. This is a ready-made check, not a constructor: call it with the value directly.
numberConstrained
t.numberConstrained(min: number,--
The smallest accepted value.
max: number--
The largest accepted value.
) → Check--
Fails with the t.numberMin or t.numberMax message.
Returns a check that passes for numbers where min <= value <= max (both inclusive).
local isPercent = t.numberConstrained(0, 100)
Errors
| Type | Description |
|---|---|
| string | If `min` or `max` is not a number (asserted when the check is built). |
numberConstrainedExclusive
t.numberConstrainedExclusive(min: number,--
The lower bound, not accepted itself.
max: number--
The upper bound, not accepted itself.
) → Check--
Fails with the t.numberMinExclusive or t.numberMaxExclusive message.
Returns a check that passes for numbers where min < value < max (both exclusive).
Errors
| Type | Description |
|---|---|
| string | If `min` or `max` is not a number (asserted when the check is built). |
match
t.match(pattern: string--
A Lua pattern.
) → Check--
Fails with "<value> failed to match pattern <pattern>".
Returns a check that passes for strings matching a Lua string pattern (string.match).
Non-strings fail with the t.string message. Anchor the pattern (^...$) if the whole
string must match.
local isHexColor = t.match("^#%x%x%x%x%x%x$")
print(isHexColor("#ff8800")) --> true
Errors
| Type | Description |
|---|---|
| string | If `pattern` is not a string (asserted when the check is built). |
optional
Returns a check that passes when the value is nil or passes check. This is how you
mark interface fields and tuple positions as optional. Failure messages are prefixed with
"(optional) ".
local IsConfig = t.interface({
Name = t.string,
Speed = t.optional(t.number), -- may be omitted
})
Errors
| Type | Description |
|---|---|
| string | If `check` is not a function (asserted when the check is built). |
tuple
t.tuple() → (...any) → (boolean,string?)--
A check that takes the arguments as varargs.
Returns a check for an argument list rather than a single value. The returned function
takes any number of arguments and checks the i-th argument against the i-th check. Extra
arguments beyond the checks are ignored; missing arguments are checked as nil, so wrap a
check in t.optional to allow it to be absent. Failures report the index:
"Bad tuple index #2:\n\t<message>".
local checkArgs = t.tuple(t.instanceIsA("Player"), t.string, t.optional(t.number))
local function giveItem(player, itemName, amount)
assert(checkArgs(player, itemName, amount))
end
keys
Returns a check that passes when the value is a table and every key passes check.
Values are not inspected. Failures read "bad key <key>:\n\t<message>".
Errors
| Type | Description |
|---|---|
| string | If `check` is not a function (asserted when the check is built). |
values
Returns a check that passes when the value is a table and every value passes check.
Keys are not inspected. Failures read "bad value for key <key>:\n\t<message>".
Errors
| Type | Description |
|---|---|
| string | If `check` is not a function (asserted when the check is built). |
map
Returns a check for dictionaries: the value must be a table, every key must pass keyCheck
and every value must pass valueCheck. Equivalent to t.keys followed by t.values. Empty
tables pass.
local isScoreboard = t.map(t.instanceIsA("Player"), t.integer)
Errors
| Type | Description |
|---|---|
| string | If either argument is not a function (asserted when the check is built). |
set
Returns a check for set-like tables of the form { [item] = true }: every key must pass
valueCheck and every value must be exactly true. Equivalent to
t.map(valueCheck, t.literal(true)).
local isNameSet = t.set(t.string)
print(isNameSet({ Alice = true, Bob = true })) --> true
array
Returns a check for proper arrays: the value must be a table whose keys are exactly
1..n with no gaps (sparse or mixed tables fail with "[array] key <k> must be sequential")
and whose every element passes check. Empty tables pass.
local isPath = t.array(t.Vector3)
print(isPath({ Vector3.zero, Vector3.one })) --> true
print(isPath({ [1] = Vector3.zero, [3] = Vector3.one })) --> false
Errors
| Type | Description |
|---|---|
| string | If `check` is not a function (asserted when the check is built). |
strictArray
Returns a check for a fixed-length, positionally typed array (a tuple stored in a table).
The value must be a sequential array with at most as many elements as there are checks,
and element i must pass check i. Missing trailing elements are checked as nil, so use
t.optional to allow them.
local isPair = t.strictArray(t.string, t.number)
print(isPair({ "Coins", 10 })) --> true
print(isPair({ "Coins", 10, true })) --> false, "[strictArray] Array size exceeds limit of 2"
Errors
| Type | Description |
|---|---|
| string | If any argument is not a function (asserted when the check is built). |
unionList
Returns a check that passes when any check in the checks array passes (a union / "or").
Checks are tried in order and the first success wins. The failure message is the generic
"bad type for union". t.union is the vararg form.
Errors
| Type | Description |
|---|---|
| string | If `checks` is not an array of functions (asserted when the check is built). |
union
Returns a check that passes when any of the given checks passes (a union / "or"). Alias:
t.some. Same as t.unionList({ ... }).
local isIdentifier = t.union(t.string, t.number)
local isPartOrModel = t.union(t.instanceIsA("BasePart"), t.instanceIsA("Model"))
some
Alias of t.union.
intersectionList
Returns a check that passes only when every check in the checks array passes (an
intersection / "and"). Checks run in order and the first failure's message is returned.
t.intersection is the vararg form.
Errors
| Type | Description |
|---|---|
| string | If `checks` is not an array of functions (asserted when the check is built). |
intersection
t.intersection() → Check--
Passes when every check passes; fails with the first failing check's message.
Returns a check that passes only when every given check passes (an intersection /
"and"). Alias: t.every. Same as t.intersectionList({ ... }). Useful for adding a
constraint to an existing check.
local isEvenInteger = t.intersection(t.integer, function(n)
return n % 2 == 0, "even number expected"
end)
every
Alias of t.intersection.
interface
Returns a check for objects (dictionaries with known field names). The value must be a table
and, for each key = check pair in checkTable, value[key] must pass check. Fields not
listed in checkTable are allowed and ignored; use t.strictInterface to forbid them.
Wrap a field's check in t.optional to make the field optional. Failures read
"[interface] bad value for <key>:\n\t<message>".
local IsItem = t.interface({
Id = t.string,
Price = t.numberMin(0),
Tags = t.optional(t.array(t.string)),
})
print(IsItem({ Id = "sword", Price = 50, Extra = true })) --> true (Extra is ignored)
Errors
| Type | Description |
|---|---|
| string | If `checkTable` is not a table of functions (asserted when the check is built). |
strictInterface
t.strictInterface() → Check--
Passes for tables with exactly the listed fields, each satisfying its check.
Like t.interface, but additionally fails if the value contains any key not present in
checkTable, with the message "[interface] unexpected field <key>". Use it for data that
crosses a trust boundary (remotes, saved data) where unknown fields should be rejected.
local IsMove = t.strictInterface({ X = t.number, Y = t.number })
print(IsMove({ X = 1, Y = 2, Z = 3 })) --> false, '[interface] unexpected field "Z"'
Errors
| Type | Description |
|---|---|
| string | If `checkTable` is not a table of functions (asserted when the check is built). |
instanceOf
t.instanceOf(className: string,--
The exact ClassName required.
) → Check--
Fails with "<className> expected, got <actual ClassName>" or a t.children message.
Returns a check that passes when the value is an Instance whose ClassName is exactly
className (no inheritance; a MeshPart is not a "Part"). Use t.instanceIsA for an
IsA comparison. If childTable is given, the instance's children are also checked with
t.children. Alias: t.instance.
local isCrate = t.instanceOf("Part", {
Lid = t.instanceIsA("BasePart"),
Prompt = t.optional(t.instanceOf("ProximityPrompt")),
})
Errors
| Type | Description |
|---|---|
| string | If `className` is not a string (asserted when the check is built). |
instance
t.instance(className: string,--
The exact ClassName required.
) → Check--
Passes for instances of exactly that class.
Alias of t.instanceOf.
instanceIsA
t.instanceIsA(className: string,--
The class (or superclass) name passed to IsA.
) → Check--
Fails with "<className> expected, got <actual ClassName>" or a t.children message.
Returns a check that passes when the value is an Instance for which value:IsA(className)
is true, so subclasses are accepted ("BasePart" matches Part, MeshPart, WedgePart...).
This is usually what you want for instance arguments. If childTable is given, the
instance's children are also checked with t.children.
local checkArgs = t.tuple(t.instanceIsA("Player"), t.instanceIsA("Tool"))
Errors
| Type | Description |
|---|---|
| string | If `className` is not a string (asserted when the check is built). |
enum
Returns a check that passes when the value is an EnumItem belonging to the given enum
(value.EnumType == enum). Items of other enums fail with
"enum of <enum> expected, got enum of <other>"; non-EnumItems fail with the t.EnumItem
message.
local isMaterial = t.enum(Enum.Material)
print(isMaterial(Enum.Material.Wood)) --> true
print(isMaterial(Enum.KeyCode.A)) --> false
Errors
| Type | Description |
|---|---|
| string | If `enum` is not an `Enum` (asserted when the check is built). |
wrap
t.wrap(callback: (A...) → R...,--
The function to guard.
) → (A...) → R...--
A function that asserts the arguments and then calls callback.
Returns a new function that first runs assert(checkArgs(...)) on its arguments and then
calls callback(...), returning whatever callback returns. checkArgs is normally a
t.tuple. This is a convenient way to publish a guarded version of a function without
editing its body.
local function setHealth(humanoid, health)
humanoid.Health = health
end
setHealth = t.wrap(setHealth, t.tuple(t.instanceIsA("Humanoid"), t.numberMin(0)))
setHealth(workspace.Dummy.Humanoid, -5) -- errors: "Bad tuple index #2: ..."
Errors
| Type | Description |
|---|---|
| string | If either argument is not a function (asserted when `wrap` is called), or, from the returned function, the message of a failed check. |
strict
t.strict() → (...any) → ()--
A function that raises the check's message if the check fails.
Turns a check into an assertion: the returned function calls assert(check(...)), so it
errors with the check's message on failure and returns nothing on success. Use it at the top
of functions or when validating data where a boolean result is not useful.
local assertConfig = t.strict(t.interface({ Speed = t.number }))
assertConfig({ Speed = "fast" }) -- error: [interface] bad value for Speed: number expected, got string
Errors
| Type | Description |
|---|---|
| string | From the returned function, the message of the failed check. |
children
t.children() → Check--
Fails with "[<FullName>.<child>] <message>" when a child does not satisfy its check.
Returns a check for an instance's child tree. The value must be an Instance; for each
name = check pair in checkTable, the child called name (or nil if there is none) is
passed to check. Wrap a check in t.optional to allow a child to be missing, and use
t.instanceOf / t.instanceIsA with their own childTable to nest deeper. Children whose
names are not in checkTable are ignored.
CAUTION
If the instance has two or more children sharing a name that appears in checkTable, the
check fails with "Cannot process multiple children with the same name", even if one of
them would have passed.
local isCharacter = t.children({
Humanoid = t.instanceOf("Humanoid"),
HumanoidRootPart = t.instanceIsA("BasePart"),
Head = t.instanceIsA("BasePart"),
})
print(isCharacter(player.Character))
Errors
| Type | Description |
|---|---|
| string | If `checkTable` is not a string-keyed table of functions (asserted when the check is built). |
exactly
This was deprecated in v1.0.0
t.exactly(...: any--
One or more values the checked value may equal.
) → Check--
Passes when the value equals one of the literals.
Old name for t.literal; behaves identically.