Luau mendukung sistem tipe gradual melalui penggunaan anotasi tipe dan inferensi tipe. Jenis ini digunakan untuk memberikan peringatan, kesalahan, dan saran yang lebih baik di Editor Skrip.
Mendefinisikan Jenis
Gunakan kata kunci type untuk mendefinisikan jenis Anda sendiri:
type Vector2 = {x: number, y: number}
Mode Penyimpangan
Ada tiga mode inferensi Luau yang dapat diatur di baris pertama dari Script :
- --!nocheck - Jangan memeriksa jenis
- --!nonstrict - Mode default untuk semua skrip, hanya menyatakan jenis variabel jika mereka secara eksplisit ditentukan
- --!strict - Menyatakan semua jenis berdasarkan ketikyang diwarisi secara eksplisit atau tersirat
Mode default untuk pemeriksa ketentuan adalah --!nonstrict . Dua mode lainnya mengontrol seberapa ketat pemeriksa ketentuan dengan inferring dan memeriksa jenis untuk variabel dan fungsi. Setiap ketidakcocokan tipe dalam script ditampilkan dalam Editor Skrip dan muncul sebagai peringatan di Jendela Analisis Skrip.
Jenis
Sebuah type annotation dapat di definisikan menggunakan operator : setelah variabel lokal, setelah definisi jenis. Secara default, dalam mode nonstrict semua variabel diberikan type any.
local foo: string = "bar"local x: number = 5
Ada empat jenis primitif yang dapat digunakan dalam anotasi:
- nil - tidak ada nilai
- boolean - true atau false
- number - nilai numerik
- string - teks
Dalam Roblox, semua Kelas, jenis data, dan enum memiliki jenis mereka sendiri yang dapat Anda periksa melawan:
local somePart: Part = Instance.new("Part")local brickColor: BrickColor = somePart.BrickColorlocal material: Enum.Material = somePart.Material
Untuk membuat jenis pilihannya, gunakan ? di akhir anotasi:
local foo: string? = nil
Ini akan memungkinkan variabel untuk menjadi jenis yang ditentukan (dalam kasus ini string ) atau nil .
Jenis Literal
Anda juga dapat menggunakan ekspresi reguler untuk mengubah nilai kata-kata ke nilai logika, bukan menggunakan string dan boolean :
local alwaysHelloWorld: "Hello world!" = "Hello world!"alwaysHelloWorld = "Just hello!" -- Ketik kesalahan: Ketik “Halo dunia!” tidak dapat dikonversi menjadi “Halo dunia!”local alwaysTrue: true = false -- Type error: Type 'false' could not be converted into 'true'
Jenis Cast
Terkadang, Anda mungkin perlu membantu pemeriksa jenis dengan mengekspresikan nilai ke jenis yang berbeda dengan operator :: :
local myNumber = 1local myString: stringmyString = myNumber -- Tidak OK; ketik kesalahan konversimyString = myNumber :: any -- Oke; semua ekspresi dapat dikastikan ke 'apa pun'local myFlag = myNumber :: boolean -- Not OK; types are unrelated
Ketik Fungsi
Pertimbangkan fungsi berikut:
local function add(x, y)
return x + y
end
Fungsi ini menambahkan x ke y , tetapi kesalahan jika salah satu atau kedua dari mereka adalah string. Luau tidak tahu bahwa fungsi ini hanya dapat menggunakan angka. Untuk menghindari 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 menunjukkan peringatan jika Anda mencoba untuk melewati apa pun yang bukan angka ke dalam fungsi:
add(5, 10)add(5, "foo") -- Type error: string could not be converted into number
Untuk mendefinisikan ketikkembalian, letakkan operator : di akhir definisi fungsi:
local function add(x: number, y: number): number
Untuk mengembalikan beberapa jenis, letakkan jenis-jenis dalam kurungan:
local function FindSource(script: BaseScript, pattern: string): (string, number)
return 42, true -- Jenis kesalahan
end
Mendefinisikan Jenis Fungsional
Jenis fungsional dapat di definisikan dengan menggunakan sintaks (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 jenis table , tetapi sebaliknya, jenis tabel ditentukan menggunakan {} sintaks. Salah satu cara mendefinisikan tabel adalah menggunakan {type} sintaks, yang mendefinisikan ketikdaftar.
local numbers: {number} = {1, 2, 3, 4, 5}local characterParts: {Instance} = LocalPlayer.Character:GetChildren()
Definisikan jenis indeks menggunakan {[indexType]: valueType} :
local numberList: {[string]: number} = {Foo = 1,Baz = 10}numberList["bar"] = true -- Type error: boolean can't convert to number
Tabel juga dapat memiliki indeks string yang jelas di dalam ketik.
type Car = {
Speed: number,
Drive: (Car) -> ()
}
local function drive(car)
-- Selalu pergi batas kecepatan
end
local taxi: Car = {Speed = 30, Drive = drive}
Variasi
Ini adalah fungsi yang menghitung jumlah dari jumlah acak nomor:
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 ketipe tidak akan menunjukkan peringatan jika Anda menyediakan 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, asign type 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)) -- Ketik kesalahan: string tidak dapat dikonversi menjadi nomor
Namun, ini tidak berfungsi saat menulis definisi tipe fungsional:
type addLotsOfNumbers = (...: number) -> number -- Expected type, got ':'
Sebagai gantinya, gunakan ...type saja untuk mendefinisikan ketikvariadik.
type addLotsOfNumbers = (...number) -> number
Persamaan dan Persimpangan
Anda bahkan dapat mendefinisikan jenis sebagai dua atau lebih jenis menggunakan persamaan atau persamaan:
type numberOrString = number | stringtype type1 = {foo: string}type type2 = {bar: number}type type1and2 = type1 & type2 -- :{foo: string} & {bar: number}local numString1: numberOrString = true -- Jenis kesalahanlocal numString2: type1and2 = {foo = "hello", bar = 1}
Mendefinisikan Jenis yang Duga
Anda dapat menggunakan fungsi typeof dalam definisi jenis untuk jenis yang diimpor:
type Car = typeof({Speed = 0,Wheels = 4}) --> Car: {Speed: number, Wheels: number}
Salah satu cara untuk menggunakan typeof adalah dengan mendefinisikan jenis metabel tabel 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
Umum
Generics adalah parameter tingkat dasar untuk jenis. Lihat objek State berikut:
local State = {Key = "TimesClicked",Value = 0}
Tanpa generik, jenis untuk objek ini akan menjadi sebagai berikut:
type State = {Key: string,Value: number}
Namun, Anda mungkin ingin jenis untuk Value berdasarkan nilai yang diterima, di mana generik datang:
type GenericType<T> = T
The <T> resents a type yang dapat ditetapkan ke apa pun. Cara terbaik untuk melihat 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}
Generics juga dapat memiliki beberapa substitusi di dalam braket.
type Map<K, V> = {[K]: V}
Untuk mengubah objek State dari sebelumnya untuk menggunakan ketikumum:
type State<T> = {Key: string,Value: T}
Umum Fungsi
Fungsi juga dapat menggunakan generik. Contoh State mengasumsikan nilai T dari argumen masuk fungsi.
Untuk mendefinisikan fungsi generik, 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>
Jenis Ekspor
Untuk membuatnya sehingga jenis dapat digunakan di luar ModuleScript, gunakan kata kunci export :
Jenis Modul di ReplicatedStorage
export type Cat = {Name: string,Meow: (Cat) -> ()}
Script 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()