이번엔 객체를 만들기 위한 객체 타입의 정의 방법에 대해서 알아보겠습니다.
타입스크립트는 두 가지 방식으로 객체 타입
을 정의할 수 있습니다. object
타입의 선언과 객체 리터럴
을 사용해서 정의하는 방식 두 가지가 존재합니다.
object
를 이용한 객체 정의는 기존에 변수에 타입을 정의하듯이 객체를 정의합니다.
let student: object = {
name: 'Tom',
grade: 4,
};
object
는 간편하게 객체를 정의할 수 있지만 한 가지 큰 문제가 발생합니다.
다음과 같은 코드는 오류가 발생합니다.
let student: object = {
name: 'Tom',
grade: 4,
};
console.log(student.name);
object에 name 프로퍼티가 없다
라고 합니다. 하지만 우린 분명 객체를 정의할 때 name
프로퍼티를 정의해두었습니다.
이런 오류가 발생하는 이유가 뭘까요?
타입스크립트에서 object
타입 정의는 해당 변수가 객체라는 것만을 의미합니다. 그 외에 그 객체가 가진 프로퍼티의 내용은 전혀 갖고 있지 않습니다. 그렇기 때문에 object
로 객체를 정의했을 경우에는 해당 변수가 객체임은 확인할 수 있지만 그 세부내용에 대해서는 접근할 수가 없게되는 것 입니다.
그래서 객체의 프로퍼티에 접근하고 싶다면 object
타입 정의 대신 객체 리터럴
방식을 이용해서 객체를 선언해주어야합니다.
객체 리터럴은 객체의 프로퍼티의 키와 타입을 직접 정의해서 객체를 정의하고 만드는 방식입니다.
let student: {
name: string;
grade: number;
} = {
name: 'Tom',
grade: 4,
};
console.log(student.name);
아까와 다르게 정상적으로 name
프로퍼티에 접근해서 내용을 출력해주었습니다.
앞으로는 객체 리터럴 형식을 사용하도록 하겠습니다.
방금 보았던 그동안 객체 프로퍼티에 접근했던
.
방식도 object에선 먹히지 않았던 것 처럼 타입스크립트에서 object를 사용한 객체 정의를 사용하기에는 여러 불편사항들이 발생합니다.
방금 코드를 작성하거나 보면서 느끼신 분들도 계시겠지만, 객체가 좀 커질 경우 이 방식이 가독성을 해칠 우려가 있다고 느껴지지 않나요?
그래서 타입스크립트에서는 타입 별칭(Type Alias)의 type 리터럴
이나 인터페이스(Interface)
라는 문법을 추가해서 객체 리터럴을 좀 더 보기 좋게 선언할 수 있는 방법들이 생겨났습니다. 이들에 대해선 다른 포스트를 통해 다루려고 합니다.
타입스크립트에서는 객체의 프로퍼티를 읽기 전용으로만 설정할 수 있습니다.
사용법은 읽기 전용으로 만들고 싶은 프로퍼티의 앞에 readonly
키워드를 붙여줍니다.
readonly 프로퍼티명: 타입;
조금 전의 코드를 예시로 읽기 전용 프로퍼티를 만들어보겠습니다.
let student: {
readonly name: string;
grade: number;
} = {
name: 'Tom',
grade: 4,
};
위 코드에서 name
프로퍼티는 이제 읽기만이 가능한 프로퍼티가 됩니다.
객체를 만들다보면 어떤 프로퍼티는 있어도되고 없어도 되는 선택적인 상황이 발생합니다. 이런 경우를 위해 타입스크립트는 선택적 프로퍼티(optional property)
를 제공하고 있습니다.
사용법은 선택적 프로퍼티로 만들고 싶은 프로퍼티의 이름 뒤에 ?
를 붙여줍니다.
프로퍼티명?: 타입;
let student: {
readonly name: string;
grade?: number;
} = {
name: 'Tom',
grade: 4,
};
위 코드에서 grade
프로퍼티 뒤에 ?
를 붙여 선택적 프로퍼티로 만들었습니다. 예를들어 입학 예정 학생이라면 이름은 있지만 학년은 아직 없는 상태겠죠? 그런 학생들에겐 grade 프로퍼티가 부여되지 않아도 오류가 발생하지 않습니다.
자바스크립트에서 했던 것 처럼 프로퍼티 일부만 가진 객체를 선언하는 것은 불가능 합니다.
let student: { readonly name: string; grade?: number; } = { name: 'Tom', grade: 4, }; let student = { name: 'Lane', //타입스크립트에서는 불가능 };