mcpField
L
luau-type-expert

luau-type-expert

github.com/dig1t開発5291 回インストール5 週間前に更新
リポジトリ

luau-type-expert について

Luau Type Expertは、型安全なLuauコードを書く開発者向けのガイダンススキルで、特に厳密な型チェックを使うプロジェクトを対象とします。型構文、型の絞り込み、ジェネリクス、一般的なエラー、Lintルール、性能を考慮した型付けを解説します。

主な機能

  1. 01厳密な型チェックモードの解説
  2. 02型注釈と型エイリアスの説明
  3. 03型の絞り込みとキャストの案内
  4. 04ジェネリクスとメタテーブルの解説
  5. 05一般的な型エラーのトラブルシューティング
  6. 06Lintと性能ルールの参照

活用シーン

  1. 01Luauファイルで厳密なチェックを有効化
  2. 02型チェックエラーの解決
  3. 03再利用可能なジェネリック型の設計
  4. 04Lintと性能パターンに沿ったコードレビュー

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/dig1t/skills --skill luau-type-expert

インストール後、Claude Code で/luau-type-expertを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
api_reference.md
common-errors.md
lint-rules.md
performance.md

詳細

Luau 型のエキスパート

厳密な型チェックに合格する、型安全で読みやすい Luau コードを書くための専門的なガイダンスです。

型モード

ファイルの先頭では必ず --!strict を使用してください。モードは 3 種類あります。

モード動作
--!nocheck型チェックを完全に無効にします
--!nonstrict不明な型は any になります(デフォルト)
--!strict型を完全に追跡し、不一致を検出します

基本文法

標準的な注釈構文(変数、関数の引数/戻り値、オプショナル ?、複数の戻り値、可変長引数、テーブル型、型エイリアス)については、references/api_reference.md を参照してください。覚えておく価値があるのは、次の点です。

-- Export for cross-module use
export type ItemRecord = { id: string, quantity: number }

-- Function type
type Callback = (player: Player, data: any) -> boolean

-- Generic aliases
type Result<T, E> = { ok: true, value: T } | { ok: false, error: E }
type Map<K, V> = { [K]: V }

-- Literal unions (discriminated)
type Status = "pending" | "active" | "completed"

-- Intersection: value has all these properties
type Person = Named & Aged

-- Function intersection (overloads)
type Stringify = ((n: number) -> string) & ((b: boolean) -> string)

型の絞り込み(リファインメント)

Luau では、条件ブロック内で type()、typeof()(Roblox インスタンス)、真偽値判定、等価性チェックを使って型が絞り込まれます。

local function process(value: string | number)
    if type(value) == "string" then
        print(value:upper())  -- value: string here
    else
        print(value + 1)      -- value: number here
    end
end

local function safePrint(msg: string?)
    if msg then
        print(msg)  -- msg: string (not nil)
    end
end

早期リターンではリファインメントが維持されます。

local function requirePlayer(player: Player?): Player
    if not player then
        error("Player required")
    end
    -- player: Player (narrowed after early return)
    return player
end

型キャスト

推論された型を上書きするには :: を使用します。

-- Cast to specific type
local data = {} :: { string }
table.insert(data, "hello")  -- OK
table.insert(data, 123)      -- Error: number not string

-- Cast result of expression
local id = tostring(123) :: string

-- Cast for API returns
local part = workspace:FindFirstChild("Part") :: Part?

キャストのルール: 片方のオペランドがもう片方のサブタイプであるか、any である必要があります。

ジェネリクス

-- Generic function
local function first<T>(arr: { T }): T?
    return arr[1]
end

-- Generic with constraint
local function clone<T>(obj: T & {}): T
    local copy = {}
    for k, v in obj :: any do
        copy[k] = v
    end
    return copy :: T
end

-- Generic type alias
type Container<T> = {
    value: T,
    set: (self: Container<T>, value: T) -> (),
    get: (self: Container<T>) -> T,
}

-- Multiple type parameters
type Pair<K, V> = { key: K, value: V }

メタテーブルと OOP

--!strict

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

type Vector2Impl = {
    __index: Vector2Impl,
    new: (x: number, y: number) -> Vector2,
    add: (self: Vector2, other: Vector2) -> Vector2,
    magnitude: (self: Vector2) -> number,
}

local Vector2: Vector2Impl = {} :: Vector2Impl
Vector2.__index = Vector2

function Vector2.new(x: number, y: number): Vector2
    return setmetatable({ x = x, y = y }, Vector2) :: Vector2
end

function Vector2:add(other: Vector2): Vector2
    return Vector2.new(self.x + other.x, self.y + other.y)
end

function Vector2:magnitude(): number
    return math.sqrt(self.x^2 + self.y^2)
end

return Vector2

よくある型エラーと修正方法

詳しいエラーの解決方法については、references/common-errors.md を参照してください。

簡単な修正方法:

エラー修正方法
Type 'X' could not be converted into 'Y'明示的なキャスト :: Y を追加するか、型を修正します
Unknown global 'X'モジュールをインポートするか、グローバル型を宣言します
Property 'X' is not compatibleプロパティの型を正確に一致させます
W_001: Unknown require適切な require パスエイリアスを使用します

luau-lsp CLI の使用方法

# Basic analysis
luau-lsp analyze src/

# With sourcemap for Roblox
luau-lsp analyze --sourcemap=sourcemap.json src/

# With definitions
luau-lsp analyze --definitions:@roblox=globalTypes.d.luau src/

# Disable all FFlags
luau-lsp analyze --no-flags-enabled src/

.luaurc の設定

{
    "languageMode": "strict",
    "lint": {
        "LocalShadow": "disabled",
        "ImportUnused": "enabled"
    },
    "aliases": {
        "@shared": "src/Shared",
        "@server": "src/Server"
    }
}

パフォーマンスを考慮した型付け

パフォーマンスパターンについては、references/performance.md を参照してください。

重要なポイント:

  • table["field"] ではなく table.field を使用します
  • メタテーブルは浅く保ちます(__index をテーブルに直接指定します)
  • 組み込み関数をローカル化します:local max = math.max
  • getfenv/setfenv は避けます(最適化が解除されます)
  • サイズが既知の場合は table.create(n) を使用します

Lint ルールのリファレンス

28 個すべての lint ルールについては、references/lint-rules.md を参照してください。

重要なルール:

  • UnknownGlobal - タイプミスを検出します
  • LocalUnused - 未使用のコードを検出します
  • ImplicitReturn - 戻り値の不一致を検出します
  • UninitializedLocal - 代入前の使用を検出します

コメント