Sprawdzanie typów

*Ta zawartość została przetłumaczona przy użyciu narzędzi AI (w wersji beta) i może zawierać błędy. Aby wyświetlić tę stronę w języku angielskim, kliknij tutaj.

Luau obsługuje system typów stopniowych poprzez użycie adnotacji typów i wnioskowania typów. Typy te są używane do zapewnienia lepszych ostrzeżeń, błędów i sugestii w Edytorze skryptów.

Zdefiniuj typ

Użyj słowa kluczowego type, aby zdefiniować własne typy:


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

Tryby wnioskowania

Istnieją trzy tryby wnioskowania typów w Luau, które można ustawić w pierwszej linii Script:

  • --!nocheck — Nie sprawdzaj typów.
  • --!nonstrict — Sprawdza tylko typy zmiennych, jeśli są one jawnie adnotowane.
  • --!strict — Sprawdza wszystkie typy na podstawie wnioskowanego lub jawnie adnotowanego typu.

Tryby --!nonstrict i --!strict kontrolują, jak rygorystyczny jest sprawdzacz typów przy wnioskowaniu i sprawdzaniu typów dla zmiennych i funkcji. Wszystkie niezgodności typów w skryptach są wyróżniane w Edytorze skryptów i są prezentowane jako ostrzeżenia w oknie Analiza skryptów.

Aby ustawić domyślny tryb dla wszystkich skryptów, który można nadpisać w razie potrzeby, zobacz Workspace.LuauTypeCheckMode.

Typy

Adnotacja typu może być zdefiniowana za pomocą operatora : po lokalnej zmiennej, a następnie definicji typu. Domyślnie w trybie nonstrict, wszystkie zmienne są przypisywane do typu any.


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

Istnieją cztery typy prymitywne, które mogą być używane w adnotacji:

  • nil - brak wartości
  • boolean - true lub false
  • number - wartość numeryczna
  • string - tekst

W ramach Roblox wszystkie klasy, typy danych i enumy mają swoje własne typy, które można sprawdzić:


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

Aby uczynić typ opcjonalnym, użyj ? na końcu adnotacji:


local foo: string? = nil

To pozwoli zmiennej przyjąć albo określony typ (w tym przypadku string), albo nil.

Typy literałowe

Możesz również rzutować ciągi i booleany na wartości literowe, zamiast używać string i boolean:


local alwaysHelloWorld: "Hello world!" = "Hello world!"
alwaysHelloWorld = "Just hello!" -- Błąd typów: Typ '"Just hello!"' nie mógł zostać przekształcony na '"Hello world!"'
local alwaysTrue: true = false -- Błąd typów: Typ 'false' nie mógł zostać przekształcony na 'true'

Rzuty typów

Czasami może być konieczne wspomaganie sprawdzacza typów poprzez jawne rzutowanie wartości na inny typ przy pomocy operatora :::


local myNumber = 1
local myString: string
myString = myNumber -- Nie OK; błąd konwersji typów
myString = myNumber :: any -- OK; wszystkie wyrażenia mogą być rzucone na 'any'
local myFlag = myNumber :: boolean -- Nie OK; typy są niepowiązane

Typowanie funkcji

Rozważ następującą funkcję:


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

Ta funkcja dodaje x do y, ale zgłasza błędy, jeśli jeden lub oba z nich są ciągami. Luau nie wie, że ta funkcja może używać tylko liczb. Aby zapobiec tej kategorii problemów, dodaj typy do parametrów:


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

Luau teraz wie, że funkcja przyjmuje dwie liczby i zgłasza ostrzeżenie, jeśli spróbujesz przekazać coś, co nie jest liczbą do funkcji:


add(5, 10)
add(5, "foo") -- Błąd typów: ciąg nie mógł zostać przekształcony na liczbę

Aby zdefiniować typ zwracany, umieść operator : na końcu definicji funkcji:


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

Aby zwrócić wiele typów, umieść typy w nawiasach:


local function FindSource(script: BaseScript, pattern: string): (string, number)
return 42, true -- Błędy typów
end

Zdefiniuj typ funkcyjny

Typ funkcyjny można zdefiniować przy użyciu składni (in) -> out. Korzystając z funkcji z poprzednich przykładów, typy funkcji to:


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

Typy tabel

Luau nie ma typu table; zamiast tego, typy tabel są definiowane przy użyciu składni {}. Jednym ze sposobów definiowania tabel jest użycie składni {type}, która definiuje typ listy.


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

Zdefiniuj typy indeksów używając {[indexType]: valueType}:


local numberList: {[string]: number} = {
Foo = 1,
Baz = 10
}
numberList["bar"] = true -- Błąd typów: boolean nie może być przekształcony na liczbę

Tabele mogą również mieć jawnie zdefiniowane indeksy łańcuchowe w typie.


type Car = {
Speed: number,
Drive: (Car) -> ()
}
local function drive(car)
-- Zawsze przestrzegaj ograniczenia prędkości
end
local taxi: Car = {Speed = 30, Drive = drive}

Wariadyki

Oto funkcja, która oblicza sumę dowolnej liczby liczb:


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

Jak można się spodziewać, ta funkcja może przyjąć dowolną wartość, a sprawdzacz typów nie zgłosi ostrzeżenia, jeśli dostarczysz nieprawidłowy typ, taki jak string.


print(addLotsOfNumbers(1, 2, 3, 4, 5)) -- 15
print(addLotsOfNumbers(1, 2, "car", 4, 5)) -- Próba dodania ciągu do liczby

Zamiast tego, przypisz typ do ..., tak jak przypisujesz dowolny inny typ:


local function addLotsOfNumbers(...: number)

I teraz, druga linia zgłasza błąd typu.


print(addLotsOfNumbers(1, 2, 3, 4, 5))
print(addLotsOfNumbers(1, 2, "car", 4, 5)) -- Błąd typów: ciąg nie mógł zostać przekształcony na liczbę

Jednak nie zadziała to przy pisaniu definicji typu funkcyjnego:


type addLotsOfNumbers = (...: number) -> number -- Oczekiwany typ, otrzymano ':'

Zamiast tego, użyj składni ...type, aby zdefiniować typ z wariadykami.


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

Unie i przecięcia

Możesz nawet zdefiniować typ jako dwa lub więcej typów przy użyciu unii lub przecięcia:


type numberOrString = number | string
type type1 = {foo: string}
type type2 = {bar: number}
type type1and2 = type1 & type2 -- {foo: string} & {bar: number}
local numString1: numberOrString = true -- Błąd typów
local numString2: type1and2 = {foo = "hello", bar = 1}

Zdefiniuj typ wnioskowany

Możesz użyć funkcji typeof w definicji typu dla typów wnioskowanych:


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

Jednym ze sposobów użycia typeof jest zdefiniowanie typu metatable przy użyciu setmetatable wewnątrz funkcji typeof:


type Vector = typeof(setmetatable({}::{
x: number,
y: number
}, {}::{
__add: (Vector, Vector|number) -> Vector
}))
-- Vector + Vector zwróci typ Vector

Generiki

Generiki na podstawowym poziomie to parametry dla typów. Rozważ następujący obiekt State:


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

Bez generików typ tego obiektu byłby następujący:


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

Jednak możesz chcieć, aby typ dla Value był oparty na nadchodzącej wartości, co jest miejscem, w którym pojawiają się generiki:


type GenericType<T> = T

<T> oznacza typ, który może być dowolny. Najlepszym sposobem na wizualizację tego jest jako typ substytucji.


type List<T> = {T}
local Names: List<string> = {"Bob", "Dan", "Mary"} -- Typ staje się {string}
local Fibonacci: List<number> = {1, 1, 2, 3, 5, 8, 13} -- Typ staje się {number}

Generiki mogą również mieć wiele substytucji w nawiasach.


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

Aby przekształcić obiekt State z wcześniejszego przykładu na używający typu generycznego:


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

Generiki funkcji

Funkcje mogą również korzystać z generików. Przykład State wnioskowuje wartość T z nadchodzących argumentów funkcji.

Aby zdefiniować funkcję generyczną, dodaj <> do nazwy funkcji:


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

Eksporty typów

Aby umożliwić użycie typu na zewnątrz ModuleScript, użyj słowa kluczowego export:

Moduł typów w ReplicatedStorage

export type Cat = {
Name: string,
Meow: (Cat) -> ()
}
Skrypt korzystający z modułu typów

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Types = require(ReplicatedStorage.Types)
local newCat: Types.Cat = {
Name = "metatablecat",
Meow = function(self)
print(`{self.Name} powiedział meow`)
end
}
newCat:Meow()
©2026 Roblox Corporation. Nazwa Roblox, logo Roblox oraz hasło „Powering Imagination” należą do naszych zarejestrowanych i niezarejestrowanych znaków towarowych na terenie Stanów Zjednoczonych oraz w innych krajach.