型チェック

*このコンテンツは、ベータ版のAI(人工知能)を使用して翻訳されており、エラーが含まれている可能性があります。このページを英語で表示するには、 こちら をクリックしてください。

Luau は、型アノテーションと型推論を用いた段階的型システムをサポートしています。これらの型は、スクリプトエディターでより良い警告、エラー、および提案を提供するために使用されます。

型を定義する

type キーワードを使用して独自の型を定義します。


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

推論モード

Script の最初の行で設定できる Luau の型推論モードは 3 つあります。

  • --!nocheck — 型をチェックしない。
  • --!nonstrict — 明示的にアノテートされている場合にのみ変数の型をアサートする。
  • --!strict — 推論された型または明示的にアノテートされた型に基づいてすべての型をアサートする。

--!nonstrict--!strict モードは、変数や関数の型推論と型チェックにおいて型チェッカーがどれだけ厳密であるかを制御します。スクリプト内の型の不一致は、スクリプトエディターで強調表示され、スクリプト分析ウィンドウで警告として表示されます。

必要に応じてオーバーライド可能なすべてのスクリプトのデフォルトモードを設定するには、Workspace.LuauTypeCheckMode を参照してください。

型アノテーションは、ローカル変数の後に : 演算子を使用して定義され、その後に型定義が続きます。デフォルトでは、nonstrict モードではすべての変数に型 any が割り当てられます。


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.BrickColor
local material: Enum.Material = somePart.Material

型をオプションにするには、アノテーションの末尾に ? を使用します。


local foo: string? = nil

これにより、変数は指定された型(この場合は string)または nil のいずれかを許可します。

リテラル型

文字列やブール値を stringboolean の代わりにリテラル値にキャストすることもできます。


local alwaysHelloWorld: "Hello world!" = "Hello world!"
alwaysHelloWorld = "Just hello!" -- 型エラー: 型 '"Just hello!"' を '"Hello world!"' に変換できません
local alwaysTrue: true = false -- 型エラー: 型 'false' を 'true' に変換できません

型キャスト

型チェックを支援するために、値を別の型に明示的にキャストする必要がある場合があります。これは :: 演算子を使用して行います。


local myNumber = 1
local myString: string
myString = myNumber -- 不可; 型変換エラー
myString = myNumber :: any -- OK; すべての式は 'any' にキャストできます
local myFlag = myNumber :: boolean -- 不可; 型が関連していません

関数の型

次の関数を考えてみましょう。


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

この関数は xy に加算しますが、どちらか一方または両方が文字列の場合はエラーになります。Luau はこの関数が数値のみを使用できることを知りません。このカテゴリの問題を防ぐために、パラメータに型を追加します。


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

Luau は、関数が 2 つの数値を受け取ることを知っており、数値以外のものを関数に渡そうとすると警告を出します。


add(5, 10)
add(5, "foo") -- 型エラー: 文字列を数値に変換できません

返り値の型を定義するには、関数定義の末尾に : 演算子を置きます。


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) -> number
type FindSource = (script: BaseScript, pattern: string) -> (string, number)

テーブル型

Luau には table 型はありません。代わりに、テーブル型は {} 構文を使用して定義されます。テーブルを定義する一つの方法は {type} 構文を使用することで、リスト型を定義します。


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 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)) -- 15
print(addLotsOfNumbers(1, 2, "car", 4, 5)) -- 数値に文字列を加算しようとしました

代わりに、... に型を割り当てます。これは他の型に割り当てるときの方法と同じです。


local function addLotsOfNumbers(...: number)

これにより、2 行目で型エラーが発生します。


print(addLotsOfNumbers(1, 2, 3, 4, 5))
print(addLotsOfNumbers(1, 2, "car", 4, 5)) -- 型エラー: 文字列を数値に変換できません

ただし、これは関数型定義を書いているときには機能しません。


type addLotsOfNumbers = (...: number) -> number -- 期待される型、':'

代わりに、可変引数型を定義するには ...type 構文を使用します。


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

ユニオンとインターセクション

ユニオンまたはインターセクションを使用して、2 つ以上の型を持つ型を定義することもできます。


type numberOrString = number | string
type type1 = {foo: string}
type type2 = {bar: number}
type type1and2 = type1 & type2 -- {foo: string} & {bar: number}
local numString1: numberOrString = true -- 型エラー
local numString2: type1and2 = {foo = "hello", bar = 1}

推論型の定義

推論型の型定義で typeof 関数を使用できます。


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

typeof を使用する一つの方法は、typeof 関数内で setmetatable を使用してメタテーブル型を定義することです。


type Vector = typeof(setmetatable({}::{
x: number,
y: number
}, {}::{
__add: (Vector, Vector|number) -> Vector
}))
-- Vector + Vector は Vector 型を返します

ジェネリクス

ジェネリクスは、基本的に型のパラメータです。以下の State オブジェクトを考えてみましょう。


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

ジェネリクスなしでは、このオブジェクトの型は次のようになります。


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

しかし、Value の型を渡される値に基づいて決定したい場合、ここでジェネリクスが役立ちます。


type GenericType<T> = T

<T> は、任意のものに設定できる型を示します。これは置き換え型として視覚化するのが最良です。


type List<T> = {T}
local Names: List<string> = {"Bob", "Dan", "Mary"} -- 型は {string} になります
local Fibonacci: List<number> = {1, 1, 2, 3, 5, 8, 13} -- 型は {number} になります

ジェネリクスには、かっこ内に複数の置き換えが含まれることもあります。


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

前述の State オブジェクトを再構築してジェネリック型を使用するには:


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

関数のジェネリクス

関数もジェネリクスを使用できます。State の例では、関数の受け取る引数から T の値を推論します。

ジェネリック関数を定義するには、関数名に <> を追加します。


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>

型のエクスポート

型が 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()
©2026 Roblox Corporation。Roblox(ロブロックス)、RobloxロゴおよびPowering Imaginationは、米国並びにその他の国における登録商標および非登録商標です。