mcpField
L
luau-type-expert

luau-type-expert

github.com/flatbedj开发068 次安装2 天前更新
代码仓库

关于 luau-type-expert

为 Luau 开发提供严格类型检查指导,面向希望编写类型安全代码的开发者。涵盖类型语法、窄化、泛型和常见错误,并包含 luau-lsp 用法。

主要功能

  1. 01严格模式与类型注解
  2. 02条件分支中的类型窄化
  3. 03类型转换与泛型
  4. 04元表和面向对象类型
  5. 05常见错误修复
  6. 06luau-lsp 与 lint 配置

适用场景

  1. 01为 Luau 文件启用严格类型检查
  2. 02处理可选值和联合类型
  3. 03排查类型不匹配及未知全局错误

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/flatbedj/roblox-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。共有三种模式:

模式行为
--!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 }

元表和面向对象编程

--!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 - 赋值前使用

评论

支持 Markdown