Luau mendukung sistem tipe bertahap melalui penggunaan anotasi tipe dan inferensi tipe.Jenis ini digunakan untuk memberikan peringatan, kesalahan, dan saran yang lebih baik di Editor Skrip.
Definisikan ketik
Gunakan kata kunci type untuk mendefinisikan jenis Anda sendiri:
type Vector2 = {x: number, y: number}
Mode inferensi
Ada tiga mode inferensi jenis Luau yang dapat ditetapkan pada baris pertama dari Script:
- --!nocheck — Jangan memeriksa jenis.
- --!nonstrict — Hanya menyatakan jenis variabel jika secara eksplisit diberi anotasi.
- --!strict — Mengklaim semua jenis berdasarkan ketikyang ditafsirkan atau secara eksplisit diberi anotasi.
Mode --!nonstrict dan --!strict mengontrol seberapa ketat pemeriksa jenis dengan inferensi dan memeriksa jenis variabel dan fungsi.Setiap jenis ketidakcocokan dalam skrip diberi sorotan di Editor Skrip dan muncul sebagai peringatan di jendela Analisis Skrip.
Jenis
Notasi tipe dapat didefinisikan menggunakan operator : setelah variabel lokal, diikuti dengan definisi jenis.Secara default, dalam mode nonstrict , semua variabel diberi tipe any.
local foo: string = "bar"local x: number = 5
Ada empat jenis primitif yang dapat digunakan dalam anotasi:
- nil - tidak ada nilai
- boolean - true or false
- number - nilai numerik
- string - teks
Di dalam Roblox, semua Kelas, jenis data, dan enum memiliki jenis sendiri yang dapat Anda periksa:
local somePart: Part = Instance.new("Part")local brickColor: BrickColor = somePart.BrickColorlocal material: Enum.Material = somePart.Material
Untuk membuat jenis opsional, gunakan ? di akhir anotasi:
local foo: string? = nil
Ini akan memungkinkan variabel menjadi jenis yang ditentukan (dalam kasus ini string ) atau nil .
Jenis literal
Anda juga dapat melemparkan string dan booleans ke nilai literal bukan dengan menggunakan string dan boolean :
local alwaysHelloWorld: "Hello world!" = "Hello world!"alwaysHelloWorld = "Just hello!" -- Kesalahan jenis: Jenis 'Hanya halo!' tidak dapat dikonversi menjadi 'Halo dunia!'local alwaysTrue: true = false -- Type error: Type 'false' could not be converted into 'true'
Jenis lemparan
Terkadang, Anda mungkin perlu membantu pemeriksa ketik dengan mengekspresikan nilai secara eksplisit ke jenis yang berbeda dengan operator :::
local myNumber = 1local myString: stringmyString = myNumber -- Tidak OK; ketik kesalahan konversimyString = myNumber :: any -- Oke; semua ekspresi dapat dilemparkan ke 'apa pun'local myFlag = myNumber :: boolean -- Not OK; types are unrelated
Tipe fungsi
Pertimbangkan fungsi berikut:
local function add(x, y)
return x + y
end
Fungsi ini menambahkan x ke y , tetapi kesalahan jika satu atau keduanya adalah string.Luau tidak tahu bahwa fungsi ini hanya dapat menggunakan angka.Untuk mencegah kategori masalah ini, tambahkan jenis ke parameter:
local function add(x: number, y: number)
return x + y
end
Luau sekarang tahu bahwa fungsi mengambil dua angka dan membuang peringatan jika Anda mencoba melewati apa pun yang bukan angka ke fungsi:
add(5, 10)add(5, "foo") -- Type error: string could not be converted into number
Untuk mendefinisikan ketikpengembalian, letakkan operator : pada akhir definisi fungsi:
local function add(x: number, y: number): number
Untuk mengembalikan beberapa jenis, letakkan jenis dalam tanda kurung:
local function FindSource(script: BaseScript, pattern: string): (string, number)
return 42, true -- Kesalahan jenis
end
Definisikan jenis ketik
Tipe fungsional dapat didefinisikan dengan menggunakan syntax (in) -> out. Menggunakan fungsi dari contoh sebelumnya, jenis fungsi adalah:
type add = (x: number, y: number) -> numbertype FindSource = (script: BaseScript, pattern: string) -> (string, number)
Jenis tabel
Luau tidak memiliki ketiktable ; sebagai gantinya, jenis tabel didefinisikan menggunakan syntax {}.Salah satu cara untuk mendefinisikan tabel adalah menggunakan syntax {type}, yang mendefinisikan ketikdaftar.
local numbers: {number} = {1, 2, 3, 4, 5}local characterParts: {Instance} = LocalPlayer.Character:GetChildren()
Tentukan jenis indeks menggunakan {[indexType]: valueType} :
local numberList: {[string]: number} = {Foo = 1,Baz = 10}numberList["bar"] = true -- Type error: boolean can't convert to number
Meja juga dapat memiliki indeks string eksplisit yang didefinisikan dalam ketik.
type Car = {
Speed: number,
Drive: (Car) -> ()
}
local function drive(car)
-- Selalu pergi batas kecepatan
end
local taxi: Car = {Speed = 30, Drive = drive}
Variadiks
Berikut adalah fungsi yang menghitung jumlah total dari jumlah angka acak:
local function addLotsOfNumbers(...)
local sum = 0
for _, v in {...} do
sum += v
end
return sum
end
Seperti yang diharapkan, fungsi ini dapat mengambil nilai apa pun, dan pemeriksa tipe tidak akan menyatakan peringatan jika Anda memberikan ketikyang tidak valid, seperti string.
print(addLotsOfNumbers(1, 2, 3, 4, 5)) -- 15print(addLotsOfNumbers(1, 2, "car", 4, 5)) -- Attempt to add string to number
Sebagai gantinya, atribusikan jenis ke ..., seperti cara Anda menetapkan ketiklain:
local function addLotsOfNumbers(...: number)
Dan sekarang, baris kedua menimbulkan kesalahan jenis.
print(addLotsOfNumbers(1, 2, 3, 4, 5))print(addLotsOfNumbers(1, 2, "car", 4, 5)) -- Kesalahan jenis: string tidak dapat dikonversi menjadi angka
Namun, ini tidak berfungsi saat menulis definisi tipe fungsional:
type addLotsOfNumbers = (...: number) -> number -- Expected type, got ':'
Sebagai gantinya, gunakan syntax ...type untuk mendefinisikan ketikvariatif.
type addLotsOfNumbers = (...number) -> number
Serikat dan persimpangan
Anda bahkan dapat mendefinisikan jenis sebagai dua atau lebih jenis menggunakan union atau persimpangan:
type numberOrString = number | stringtype type1 = {foo: string}type type2 = {bar: number}type type1and2 = type1 & type2 -- {foo: string} & {bar: number}local numString1: numberOrString = true -- Kesalahan jenislocal numString2: type1and2 = {foo = "hello", bar = 1}
Definisikan ketikyang diinduksi
Anda dapat menggunakan fungsi typeof dalam definisi jenis untuk jenis yang diinduksi:
type Car = typeof({Speed = 0,Wheels = 4}) --> Car: {Speed: number, Wheels: number}
Salah satu cara untuk menggunakan typeof adalah dengan mendefinisikan jenis metabel menggunakan setmetatable di dalam fungsi typeof:
type Vector = typeof(setmetatable({}::{x: number,y: number}, {}::{__add: (Vector, Vector|number) -> Vector}))-- Vector + Vector would return a Vector type
Generik
Generatorik berada pada parameter tingkat dasar untuk jenis. Pertimbangkan objek berikut State :
local State = {Key = "TimesClicked",Value = 0}
Tanpa generik, jenis untuk objek ini akan seperti berikut:
type State = {Key: string,Value: number}
Namun, Anda mungkin ingin jenis untuk Value berbasis pada nilai masuk, di mana generik masuk:
type GenericType<T> = T
The <T> menunjukkan jenis yang dapat ditetapkan ke apa pun. Cara terbaik untuk visualisasi ini adalah sebagai ketikpengganti.
type List<T> = {T}local Names: List<string> = {"Bob", "Dan", "Mary"} -- Jenis menjadi {string}local Fibonacci: List<number> = {1, 1, 2, 3, 5, 8, 13} -- Type becomes {number}
Generatorik juga dapat memiliki banyak substitusi di dalam kurungan.
type Map<K, V> = {[K]: V}
Untuk mengubah ulang objek State dari sebelumnya untuk menggunakan ketikumum:
type State<T> = {Key: string,Value: T}
Fungsi generik
Fungsi juga dapat menggunakan generik. Contoh State menginterpretasikan nilai T dari argumen masuk fungsi.
Untuk mendefinisikan fungsi umum, tambahkan <> ke nama fungsi:
local function State<T>(key: string, value: T): State<T>
return {
Key = key,
Value = value
}
end
local Activated = State("Activated", false) -- Negara< boolean >
local TimesClicked = State("TimesClicked", 0) -- State<number>
Tipe ekspor
Untuk membuatnya sehingga jenis dapat digunakan di luar ModuleScript , gunakan kata kunci export:
Tipe Modul di ReplicatedStorage
export type Cat = {Name: string,Meow: (Cat) -> ()}
Skrip Menggunakan Modul Jenis
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()