Luau は、タイプアノーテーションとタイプ推定を使用して、グラデーションタイプのシステムをサポートします。これらのタイプは、スクリプトエディタ でより良い警告、エラー、および提案を提供するために使用されます。
タイプの定義
入力ype キーワードを使用して、自分のタイプを定義します:
type Vector2 = {x: number, y: number}
推定モード
Class.Script の最初の行に設定できる Luau タイプのインフェランスモードは 3つあります:
- --!nocheck - タイプをチェックしないでください
- --!nonstrict - すべてのスクリプトのデフォルトモードで、明示的にアノートされていない場合は変数型のみを要求します
- --!strict - 推定されたまたは明示されたタイプに基づいてすべてのタイプをアセットします
タイプチェッカーのデフォルトモードは --!nonstrict です。他の 2 つのモードは、タイプチェッカーが変数と関数の類型を推定する際にどれくらい厳重かを制御します。スクリプト内の任意のタイプミスマッチは、スクリプトエディター でスクリプトのタイプがマッチし、
タイプ
タイプアノーテーションは、ローカル変数の後にある : オペレーターを使用して定義できます。デフォルトでは、 nonstrict モードでは、すべての変数にタイプが割り当てられます。
local foo: string = "bar"local x: number = 5
アノтацииで使用できる 4つのプリミティブなタイプがあります:
- nil - 値なし
- boolean - true または false
- number - 数値
- string - テキスト
Roblox 内のすべてのクラス、データ型、および数値のタイプには、チェックできる自分のタイプがあります:
local somePart: Part = Instance.new("Part")local brickColor: BrickColor = somePart.BrickColorlocal material: Enum.Material = somePart.Material
タイプをオプションにするには、アノーテーションの最後に ? を使用します:
local foo: string? = nil
これにより、変数が指定されたタイプ(この場合 string または nil )であるか、または指定されたタイプと同等のタイプであることが保証されます。
文字通りのタイプ
また、 string と boolean を使用する代わりに、文字列とブールーアンを文字通りの値に変換できます:
local alwaysHelloWorld: "Hello world!" = "Hello world!"alwaysHelloWorld = "Just hello!" -- タイプエラー: "Hello world!" を "Just hello!" に変換できませんlocal alwaysTrue: true = false -- Type error: Type 'false' could not be converted into 'true'
型 Casts
場合には、:: オペレーターを含めて、タイプチェッカーに明示的に値を別のタイプにキャストする必要があります。
local myNumber = 1local myString: stringmyString = myNumber -- OKではありません; 変換エラーをタイプするmyString = myNumber :: any -- OK; すべてのエクスプレッションは「任意の」にキャストできますlocal myFlag = myNumber :: boolean -- Not OK; types are unrelated
機能タイピング
次の関数を考慮してください:
local function add(x, y)
return x + y
end
この関数は x を y に追加しますが、1つまたは両方が文字列である場合はエラーが発生します。Luauは、この関数が数字のみを使用できることを知っていません。このカテゴリの問題を防ぐには、パラメータにタイプを追加します:
local function add(x: number, y: number)
return x + y
end
Luau は、関数が 2つの数字を取ることを知り、数字でないものを関数に入れようとした場合、警告を表示します:
add(5, 10)add(5, "foo") -- Type error: string could not be converted into number
操作入力 を使用して機能定義の最後に : オペレーターを置くことで、 タイプを定義できます。
local function add(x: number, y: number): number
複数のタイプを返すには、親に型を置きます:
local function FindSource(script: BaseScript, pattern: string): (string, number)
return 42, true -- タイプエラー
end
機能型を定義する
機能型は、 (in) -> out 構文を使用して定義できます。以前の例から機能型のタイプは次のとおりです:
type add = (x: number, y: number) -> numbertype FindSource = (script: BaseScript, pattern: string) -> (string, number)
テーブルの種類
Luau には table タイプはありませんが、代わりにテーブルタイプは {} 構文を使用して定義されています。テーブルを定義する 1つの方法は、{type} 構文を使用することです。これは、リストタイプを定義する 1>typ入力1> 構文を使用入力ます。
local numbers: {number} = {1, 2, 3, 4, 5}local characterParts: {Instance} = LocalPlayer.Character:GetChildren()
[indexType]: valueType を使用してインデックスタイプを定義する:
local numberList: {[string]: number} = {Foo = 1,Baz = 10}numberList["bar"] = true -- Type error: boolean can't convert to number
テーブルには、入力類で明示的なストリングインデックスも定義できます。
type Car = {
Speed: number,
Drive: (Car) -> ()
}
local function drive(car)
-- 常にスピード制限に従う
end
local taxi: Car = {Speed = 30, Drive = drive}
変数
以下は、任意の数の合計を計算する関数です:
local function addLotsOfNumbers(...)
local sum = 0
for _, v in {...} do
sum += v
end
return sum
end
期待通り、この関数は任意の値を取得でき、タイプチェッカーは無効なタイプを提供することなどで警告を表示しません。たとえ、string などの無効なタイプを提供しても、タイプチェッカーは警告を表示しません。
print(addLotsOfNumbers(1, 2, 3, 4, 5)) -- 15print(addLotsOfNumbers(1, 2, "car", 4, 5)) -- Attempt to add string to number
代わりに、... にタイプを割り当てるのと同じ方法で、他のタイプを割り当てる:
local function addLotsOfNumbers(...: number)
そして、2行目の行にはタイプエラーが発生します。
print(addLotsOfNumbers(1, 2, 3, 4, 5))print(addLotsOfNumbers(1, 2, "car", 4, 5)) -- タイプエラー: 文字列は数値に変換できませんでした
ただし、機能的なタイプの定義を作成するときは、これは機能しません:
type addLotsOfNumbers = (...: number) -> number -- Expected type, got ':'
代わりに、 ...type を使用して変異的なタイ入力を定義します。
type addLotsOfNumbers = (...number) -> number
ユニオンとインターセクション
ユニオンまたは交差点を使用して、タイプを 2 以上に定義できます:
type numberOrString = number | stringtype type1 = {foo: string}type type2 = {bar: number}type type1and2 = type1 & type2 -- {foo: 文字列tring} & {bar: number}local numString1: numberOrString = true -- エラーをタイプするlocal numString2: type1and2 = {foo = "hello", bar = 1}
暗黙のタイプを定義する
型 定義における 型 関数は、暗示されたタイプに対応する:
type Car = typeof({Speed = 0,Wheels = 4}) --> Car: {Speed: number, Wheels: number}
setmetatable を使用して、setmetatable 関数の内部でメタテーブルタイプを定義する方法は次のとおりです:
type Vector = typeof(setmetatable({}::{x: number,y: number}, {}::{__add: (Vector, Vector|number) -> Vector}))-- Vector + Vector would return a Vector type
一般
ジェネリックは、種類の基本レベルのパラメータです。次の State オブジェクトを考慮してください:
local State = {Key = "TimesClicked",Value = 0}
ジェネリックななしで、このオブジェクトのタイプは次のとおりになります:
type State = {Key: string,Value: number}
しかし、Value のタイプを入力している値に基づいている必要があります。ここにジェネリックが入ります:
type GenericType<T> = T
The <T> は、何に設定できるかを示すタイプを表します。これを最高のビジュアル化方入力として、代替タイプとして表示する方法です。
type List<T> = {T}local Names: List<string> = {"Bob", "Dan", "Mary"} -- Type が {strin文字列} になりますlocal Fibonacci: List<number> = {1, 1, 2, 3, 5, 8, 13} -- Type becomes {number}
ジェネリックは、ブラケット内に複数の代用を持つこともできます。
type Map<K, V> = {[K]: V}
以前の State オブジェクトを再作成して、一般的なタイプを使用するために:
type State<T> = {Key: string,Value: T}
機能一般
機能には、ジェネリックを使用することもできます。The State 例は、機能の入ってくる引数から T の値を推定します。
一般的な関数を定義するには、関数名に <> を追加します:
local function State<T>(key: string, value: T): State<T>
return {
Key = key,
Value = value
}
end
local Activated = State("Activated", false) -- 状態<button>
local TimesClicked = State("TimesClicked", 0) -- State<number>
エクスポートをタイプ
Class.ModuleScript 以外の場合は、export キーワードを使用してください:
ReplicatedStorage のタイプモジュール
export type Cat = {Name: string,Meow: (Cat) -> ()}
タイプモジュールを使用するスクリプト
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()