유형 검사

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

Luau는 형식 노트, 형식 추론 및 형식 인식을 사용하여 단계적 형식 시스템을 지원합니다. 이러한 형식은 스크립트 편집기에서 더 나은 경고, 오류 및 제안을 제공하는 데 사용됩니다.

형식 정의

자신의 형식을 정의하려면 type 키워드를 사용하세요.


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

유추 모드

Class.Script의 첫 번째 줄에 설정할 수 있는 세 가지 Luau 유형 유추 모드가 있습니다.

  • --!nocheck - 형식을 확인하지 마십시오.
  • --!nonstrict - 모든 스크립트의 기본 모드이며, 명시적으로 지정된 변수 유형만 변수 형식을 지정합니다.
  • --!strict - 명시적으로 지정된 형식이나 명시적으로 지정된 입력기반으로 모든 형식을 주장합니다.

유형 검사기의 기본 모드는 --!nonstrict 입니다. 다른 두 모드는 유형 검사기가 변수 및 함수에 대해 얼마나 엄격한지 제어합니다. 스크립트에서 발생하는 모든 유형 오류는 스크립트 편집기스크립트 분석 창에 표시됩니다.

형식

형식 지정자는 형식 정의 뒤에 로컬 변수 후에 사용할 수 있는 : 연산자를 사용하여 정의할 수 있습니다. 기본적으로 형식 지정자는 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!" -- 형식 오류: "Hello world!"로 변환할 수 없는 형식 "Just hello!"
local alwaysTrue: true = false -- Type error: Type 'false' could not be converted into 'true'

캐스트 유형

때로는 값을 :: 연산자로 명시적으로 다른 형식으로 캐스팅하여 형식 검사기를 도울 필요가 있습니다.


local myNumber = 1
local myString: string
myString = myNumber -- OK하지 않습니다; 변환 오류 입력
myString = myNumber :: any -- OK; 모든 식을 'any'로 캐스트할 수 있습니다.
local myFlag = myNumber :: boolean -- Not OK; types are unrelated

함수 작성

다음 함수를 고려하십시오.


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") -- 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) -> 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 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

기대했던 대로, 이 함수는 모든 값을 가져올 수 있으며 유형 검사기는 잘못된 입력제공하는 경우 경고를 표시하지 않습니다. 문자열 등의 유형이 있습니다.


print(addLotsOfNumbers(1, 2, 3, 4, 5)) -- 15
print(addLotsOfNumbers(1, 2, "car", 4, 5)) -- Attempt to add string to number

대신, ... 에 유형을 할당하세요, 다른 입력할당하는 것과 동일합니다.


local function addLotsOfNumbers(...: number)

이제 두 번째 줄에서 형식 오류가 발생합니다.


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

그러나 기능 형식 정의를 작성할 때는 작동하지 않습니다.


type addLotsOfNumbers = (...: number) -> number -- Expected type, got ':'

대신, 구문 ...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}

tipo 을 사용하는 하나의 방법은 setmetatable 을 사용하여 typeof 함수 내에서 메타테이블 유형을 정의하는 것입니다.


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

T 는 모든 것에 설정할 수 있는 형식을 나타냅니다. 이 형식을 가장 잘 시각화하는 방법은 대체 입력.


type List<T> = {T}
local Names: List<string> = {"Bob", "Dan", "Mary"} -- 형식이 {문자열}이 됩니다.
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
}

함수 제네릭

함수는 제네릭을 사용할 수도 있습니다. 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의 Type Module

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()