타입 검사

*이 콘텐츠는 AI(베타)를 사용해 번역되었으며, 오류가 있을 수 있습니다. 이 페이지를 영어로 보려면 여기를 클릭하세요.

Luau는 타입 주석과 타입 추론을 사용하여 점진적인 타입 시스템을 지원합니다. 이러한 타입은 스크립트 편집기에서 더 나은 경고, 오류 및 제안을 제공하는 데 사용됩니다.

타입 정의하기

type 키워드를 사용하여 자신만의 타입을 정의하세요:


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

추론 모드

Script의 첫 번째 줄에 설정할 수 있는 세 가지 Luau 타입 추론 모드가 있습니다:

  • --!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는 함수가 두 개의 숫자를 사용하며, 숫자가 아닌 값을 함수에 전달하려고 하면 경고를 발생시킵니다:


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)

이제 두 번째 줄은 타입 오류를 발생시킵니다.


print(addLotsOfNumbers(1, 2, 3, 4, 5))
print(addLotsOfNumbers(1, 2, "car", 4, 5)) -- 타입 오류: 문자열을 숫자로 변환할 수 없습니다.

하지만, 함수 타입 정의를 작성할 때는 이 기능이 작동하지 않습니다:


type addLotsOfNumbers = (...: number) -> number -- 예상 타입과 ':'

대신, 가변 타입을 정의하기 위해 구문 ...type을 사용하세요.


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

유니온 및 교차 타입

유니온 또는 교차를 사용하여 두 개 이상의 타입으로 타입을 정의할 수도 있습니다:


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 키워드를 사용하세요:

Types Module in 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'은 미국 및 기타 국가 내 당사의 등록 및 미등록 상표입니다.