Tipo de Comprobación

*Este contenido se traduce usando la IA (Beta) y puede contener errores. Para ver esta página en inglés, haz clic en aquí.

Luau soporta un sistema de tipo gradual a través del uso de anotaciones de tipo y inferencia de tipo. Estos tipos se utilizan para proporcionar mejores advertencias, errores y sugerencias en el Editor de Scripts.

Definir un tipo

Usa la palabra clave type para definir tus propios tipos:


type Vector2 = {x: number, y: number}

Modos de inferencia

Hay tres modos de inferencia de tipo Luau que se pueden configurar en la primera línea de un Script :

  • --!nocheck - No verifique los tipos
  • --!nonstrict - Modo por defecto para todos los scripts, solo afirma tipos de variables si se especifican explícitamente
  • --!strict - Afirma todos los tipos según el introducirinferido o expresamente anotado

El modo predeterminado para el tipo checker es --!nonstrict . Los otros dos modos controlan la estrictez del tipo checker con inferir y verificar tipos para variables y funciones. Cualquier tipo de desacuerdo en los scripts se destaca en el Editor de script y se muestra como advertencias en la ventana Análisis de script.

Tipos

Una anotación de tipo se puede definir utilizando el operador : después de una variable local, seguido por una definición de tipo. Por defecto, en el modo nonstrict, todas las variables se asignan el tipo any .


local foo: string = "bar"
local x: number = 5

Hay cuatro tipos primitivos que se pueden usar en una anotación:

  • nil - sin valor
  • boolean - true o false
  • number - un valor numérico
  • string - texto

Dentro de Roblox, todas las Clases, tipos de datos y enums tienen sus propios tipos que puedes verificar contra:


local somePart: Part = Instance.new("Part")
local brickColor: BrickColor = somePart.BrickColor
local material: Enum.Material = somePart.Material

Para hacer un tipo opcional, usa un ? al final de la anotación:


local foo: string? = nil

Esto permitirá que la variable sea o el tipo especificado (en este caso string ) o nil .

Tipos Literales

También puede usar fórmulas para castizar valores numéricos y de texto en lugar de usar string y boolean :


local alwaysHelloWorld: "Hello world!" = "Hello world!"
alwaysHelloWorld = "Just hello!" -- Tipo de error: No se puede convertir el tipo «Just hello!» en «Hello mundo!»
local alwaysTrue: true = false -- Type error: Type 'false' could not be converted into 'true'

Tipos de Casts

A veces, puede que deba ayudar al tipochecker al proporcionarle explícitamente un valor a un tipo diferente con el operador :: :


local myNumber = 1
local myString: string
myString = myNumber -- No está bien; tipo error de conversión
myString = myNumber :: any -- OK; todas las expresiones se pueden cast a ' cualquier'
local myFlag = myNumber :: boolean -- Not OK; types are unrelated

Tipo de función

Considera la siguiente función:


local function add(x, y)
return x + y
end

Esta función agrega x a y , pero los errores si uno o ambos son una cadena. Luau no sabe que esta función solo puede usar números. Para evitar esta categoría de problema, agregue tipos a los parámetros:


local function add(x: number, y: number)
return x + y
end

Luau ahora sabe que la función toma dos números y lanza una advertencia si intentas pasar algo que no sea un número a la función:


add(5, 10)
add(5, "foo") -- Type error: string could not be converted into number

Para definir un introducirde regreso, pon un operador : al final de la definición de la función:


local function add(x: number, y: number): number

Para返回多个类型,请将类型放置在括号中:


local function FindSource(script: BaseScript, pattern: string): (string, number)
return 42, true -- Tipos de errores
end

Definir un tipo funcional

Un tipo funcional se puede definir por el uso de la sintaxis (in) -> out . Usando las funciones de los ejemplos anteriores, los tipos de las funciones son:


type add = (x: number, y: number) -> number
type FindSource = (script: BaseScript, pattern: string) -> (string, number)

Tipos de tabla

Luau no tiene un introducirde table sino que los tipos de tabla se definen utilizando la sintaxis {}. Una manera de definir tablas es usar la sintaxis {type}, que define un introducirde lista.


local numbers: {number} = {1, 2, 3, 4, 5}
local characterParts: {Instance} = LocalPlayer.Character:GetChildren()

Defina los tipos de índice usando {[indexType]: valueType} :


local numberList: {[string]: number} = {
Foo = 1,
Baz = 10
}
numberList["bar"] = true -- Type error: boolean can't convert to number

Las tablas también pueden tener índices de cuerda explícitos definidos en un introducir.


type Car = {
Speed: number,
Drive: (Car) -> ()
}
local function drive(car)
-- Siempre vaya al límite de velocidad
end
local taxi: Car = {Speed = 30, Drive = drive}

Variadics

Aquí está una función que calcula la suma de una cantidad de números arbitraria:


local function addLotsOfNumbers(...)
local sum = 0
for _, v in {...} do
sum += v
end
return sum
end

Como se espera, esta función puede tomar cualquier valor, y el tipochecker no mostrará una advertencia si proporciona un introducirinválido, como un string .


print(addLotsOfNumbers(1, 2, 3, 4, 5)) -- 15
print(addLotsOfNumbers(1, 2, "car", 4, 5)) -- Attempt to add string to number

En cambio, asigna un tipo a ..., como lo harías con cualquier otro introducir:


local function addLotsOfNumbers(...: number)

Y ahora, la segunda línea genera un error de tipo.


print(addLotsOfNumbers(1, 2, 3, 4, 5))
print(addLotsOfNumbers(1, 2, "car", 4, 5)) -- Tipo de error: no se pudo convertir la cadena en número

Sin embargo, esto no funciona al escribir una definición de tipo funcional:


type addLotsOfNumbers = (...: number) -> number -- Expected type, got ':'

En cambio, usa la sintaxis ...type para definir un introducirvariadico.


type addLotsOfNumbers = (...number) -> number

Uniones y Intersecciones

Incluso puede definir un tipo como dos o más tipos utilizando una unión o intersección:


type numberOrString = number | string
type type1 = {foo: string}
type type2 = {bar: number}
type type1and2 = type1 & type2 -- :{foo: cadena} y {bar: number}
local numString1: numberOrString = true -- Tipo de error
local numString2: type1and2 = {foo = "hello", bar = 1}

Definir un tipo implicado

Puedes usar la función typeof en una definición de tipo para los tipos inferidos:


type Car = typeof({
Speed = 0,
Wheels = 4
}) --> Car: {Speed: number, Wheels: number}

Una manera de usar typeof es definir un tipo de metaverso usando setmetatable dentro de la función typeof тип :


type Vector = typeof(setmetatable({}::{
x: number,
y: number
}, {}::{
__add: (Vector, Vector|number) -> Vector
}))
-- Vector + Vector would return a Vector type

Genéricos

Los genericos están a nivel de parámetros básicos para los tipos. Considere el siguiente objeto State :


local State = {
Key = "TimesClicked",
Value = 0
}

Sin genéricos, el tipo para este objeto sería como sigue:


type State = {
Key: string,
Value: number
}

Sin embargo, puede que quieras el tipo para Value que se basa en el valor recibido, donde es donde entran los genéricos:


type GenericType<T> = T

El <T> muestra un tipo que se puede configurar para cualquier cosa. La mejor manera de visualizar esto es como un introducirde sustitución.


type List<T> = {T}
local Names: List<string> = {"Bob", "Dan", "Mary"} -- El tipo se convierte en {cadena}
local Fibonacci: List<number> = {1, 1, 2, 3, 5, 8, 13} -- Type becomes {number}

Las genéricas también pueden tener múltiples sustituciones dentro de los brackets.


type Map<K, V> = {[K]: V}

Para reutilizar el objeto State desde antes para usar un introducirgenérico:


type State<T> = {
Key: string,
Value: T
}

Genéricos de función

Las funciones también pueden usar genéricos. El ejemplo State inferir el valor de T de los argumentos entrantes de la función.

Para definir una función genérica, añade un <> a la función:


local function State<T>(key: string, value: T): State<T>
return {
Key = key,
Value = value
}
end
local Activated = State("Activated", false) -- Estado<Booleano>
local TimesClicked = State("TimesClicked", 0) -- State<number>

Tipo de Exportaciones

Para hacer que un tipo se puede usar fuera de un ModuleScript , use la palabra clave de export :

Tipos de módulo en ReplicatedStorage

export type Cat = {
Name: string,
Meow: (Cat) -> ()
}
Script Usando el Módulo de Tipos

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Types = require(ReplicatedStorage.Types)
local newCat: Types.Cat = {
Name = "metatablecat",
Meow = function(self)
print(`{self.Name} said meow`)
end
}
newCat:Meow()