Types¶
Built-in types¶
-
class nil¶
The type
nilhas one single value, nil, whose main property is to be different from any other value; it usually represents the absence of a useful value.
-
class boolean¶
The type
booleanhas two values, false and true. Bothniland false make a condition false; any other value makes it true.
-
class number¶
Lua uses two internal representations for numbers: integer and float. It has explicit rules about when each representation is used, but it also converts between them automatically as needed.
EmmyLua, on the other hand, allows explicitly annotating which representation is expected. The
numbertype can contain both integer and float values. Theintegeris a sub-type ofnumber, and only allows integer values.See also
Lua’s manual on value types.
-
class integer¶
The type
integeris a sub-type ofnumberthat only allows numbers with integer representation.
-
class userdata¶
The type
userdatais provided to allow arbitrary C data to be stored in Lua variables. A userdata value represents a block of raw memory. There are two kinds of userdata:userdata, which is an object with a block of memory managed by Lua, andlightuserdata, which is simply a C pointer value.See also
Lua’s manual on value types.
-
class lightuserdata¶
The type
lightuserdatais a sub-type ofuserdatathat only allows values with light userdata representation.
-
class thread¶
The type
threadrepresents independent threads of execution and it is used to implement coroutines. Lua threads are not related to operating-system threads. Lua supports coroutines on all systems, even those that do not support threads natively.
-
class table<K, V>¶
The type table implements associative arrays, that is, arrays that can have as indices not only numbers, but any Lua value except
nilandNaN. (Not a Number is a special floating-point value used by the IEEE 754 standard to represent undefined or unrepresentable numerical results, such as0/0.)While lua allows mixing types of keys and values in a table, EmmyLua has an option to specify their exact types. Simply using type
tablecreates a heterogeneous table (equivalent totable<unknown, unknown>), while explicitly providing key and value types creates a homogeneous table:--- @type table local tableWithArbitraryData = {} --- @type table<string, integer> local tableWithStringKeysAndIntValues = {}You can also specify the exact shape of a table by using a table literal:
--- @type { username: string, age: integer } local User = { ... }See also
Lua’s manual on value types.
-
class any¶
The type
anyis compatible with any other type. That is, all types can be converted to and fromany.This type is a way to bypass type checking system and explicitly tell EmmyLua that you know what you’re doing.
-
class unknown¶
The type
unknownis similar toany, but signifies a different intent.While
anyis a way to say “I know what I’m doing”,unknownis a way to say “better check this value before using it”.
-
class self¶
A special type used with class methods. It can be thought of as a generic parameter that matches type of the function’s implicit argument
self. That is, when a function is called via colon notation (i.e.table:method()),selfis replaced with the type of expression before the colon.This is especially handy when dealing with inheritance. Consider the following example:
--- @class Base local Base = {} --- @return self function Base:new() return setmetatable({}, { __index=self }) end --- @class Child: Base local Child = setmetatable({}, { __index=Base }) local child = Child:new()Here, EmmyLua infers type of
childto beChild, even thoughnewwas defined in its base class. This is becausenewusesselfas its return type.
Metaprogramming library¶
-
alias std.NotNull<T> =
sub<T,nil>¶ A type for
assertfunction. Given a nullable typeTexpands to a non-nullable version ofT.For example, if
Tisstring?, thenstd.NotNull<T>will bestring.
-
alias std.Unpack<T, Start, End> =
unknown¶ A type for
table.unpackfunction. Given a typeTand optional literal typesStartandEnd, expands to the type of expressiontable.unpack(t, start, end).Example:
--- @generic T --- @param list T --- @return std.Unpack<T> function customUnpack(list) end local a, b, c = customUnpack({1, 2, 3})Here,
a,bandcwill be inferred as integers.
-
alias std.RawGet<T, K> =
unknown¶ A type for
rawgetfunction. Given a typeTand a literal typeK, expands to the type of expressionrawget(t, k).Example:
--- @class Example --- @field value integer --- @type std.RawGet<Example, "value"> local valueHere,
std.RawGet<Example, "value">will be expanded tointeger.
-
alias std.ConstTpl<T> =
unknown¶ A wrapper for matching literal types in generics.
By default, generics variables that match literal values decay to values’ base types:
--- @generic T --- @param x T --- @return T local function id(x) return x end local original --- @type "literal" local value = id(original)Here, type of
valuewill be inferred asstringeven thoughoriginal’s type was"literal".We can prevent this behavior by wrapping generic pattern for
Tintostd.ConstTpl<T>:--- @generic T --- @param x std.ConstTpl<T> --- @return T local function id(x) return x end local original --- @type "literal" local value = id(original)Here, type of
valuewill be inferred as"literal".