Pemeriksaan jenis

*Konten ini diterjemahkan menggunakan AI (Beta) dan mungkin mengandung kesalahan. Untuk melihat halaman ini dalam bahasa Inggris, klik di sini.

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.BrickColor
local 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 = 1
local myString: string
myString = myNumber -- Tidak OK; ketik kesalahan konversi
myString = 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) -> number
type 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)) -- 15
print(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 | string
type type1 = {foo: string}
type type2 = {bar: number}
type type1and2 = type1 & type2 -- {foo: string} & {bar: number}
local numString1: numberOrString = true -- Kesalahan jenis
local 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()