객체(Object)
ReScript의 객체는 레코드와 비슷합니다. 하지만,
타입 선언이 필요 없습니다.
레코드와 달리 구조적(structural)이고 다형성적(polymorphic)입니다.
객체가 JS로부터 전달된 것이 아니면 업데이트할 수 없습니다.
패턴 매칭을 지원하지 않습니다.
ReScript 레코드는 깔끔한 JavaScript 객체로 컴파일될 수 있지만, 보시다시피 JS 객체를 모방하거나 바인딩할 때는 ReScript의 객체가 더 나은 후보입니다.
타입 선언
레코드와 달리 선택적입니다. 객체의 타입은 값에서 유추되므로 객체의 타입 선언을 굳이 작성할 필요가 없습니다. 그럼에도 불구하고, 타입 선언 문법을 보여드리자면 이러합니다.
레코드 타입의 문법처럼 보이지만 필드 이름이 따옴표로 감싸져 있습니다.
생성
다음과 같이 새로운 객체를 만들 수 있습니다.
참고: 위에서 언급한 바와 같이, 여기서 me
는 레코드와 달리, "age"
와 "name"
의 필드를 사용해 적합한 타입 선언을 찾으려고 하지 않습니다. 대신에 me
타입은 {"age": int, "name": string}
로 추론됩니다. 이점은 편리하지만, 다음과 같이 의도치 않은 코드가 오류 없이 타입 검사를 통과한다는 것을 의미합니다.
이는 타입 검사기가 me
와 person
타입을 일치시키려 하지 않기 때문입니다. 객체의 값을 미리 선언된 객체 타입으로 강제 지정하려면 다음과 같이 값에 어노테이션을 주면 됩니다.
RESlet me: person = {
"age": "hello!"
}
이제 타입 시스템은 정상적으로 오류를 보고할 것입니다.
접근
변경
객체가 JavaScript 측에서 가져온 바인딩이 아니면 수정이 허용되지 않습니다. JS 측에서 가져온 바인딩의 경우, 다음과 같이 =
를 사용합니다.
병합 타입
하나의 객체 타입 정의를 다른 객체로 확장하고 싶다면 다음과 같이 ...
을 사용하세요.
이것은 객체 값이 아닌 객체 타입에서만 작동합니다!
사용 팁과 트릭
객체가 타입 선언이 필요하지 않는 데다 ReScript가 모든 타입을 알아서 추론해주기 때문에, 모든 JavaScript API에 매우 빠르고 쉽게 바인딩할 수 있습니다. 그러나 안전하지는 않습니다. 다음에서 JS 출력 탭을 확인하세요.
// The type of document is just some random type 'a
// that we won't bother to specify
@val external document: 'a = "document"
// call a method
document["addEventListener"]("mouseup", _event => {
Js.log("clicked!")
})
// get a property
let loc = document["location"]
// set a property
document["location"]["href"] = "rescript-lang.org"
이곳에 사용된 external
기법은 뒤에서 더 자세히 다룰 예정입니다. 이것은 특정 라이브러리에 대한 바인딩이 존재하는지에 대한 걱정 없이 일부 ReScript 코드를 작성하기 시작할 수 있는 훌륭한 방법입니다.