본문 바로가기
웹 프로그래밍/JavaScript | TypeScript

[한 입 크기로 잘라먹는 TypeScript] CH2. 타입스크립트 기본 2(3.객체, 4.타입 별칭과 인덱스 시그니쳐, 5.열거형 타입)

by 청량리 물냉면 2024. 4. 10.
반응형

chapter 2. 타입스크립트 기본

3. 객체

✅ 객체 타입을 정의하는 방법

1️⃣ object로 정의하기

let user: object = {
  id: 1,
  name: "kim",
};

user.id; //오류 발생

 

체 생성과 타입 정의를 잘해주었는데도 `user.id`를 이용해 객체의 프로퍼티에 접근하려 하면 오류가 발생한다.

👉 원인: 타입스크립트의 object 타입은 객체의 프로퍼티에 대한 어떤 정보도 가지고 있지 않기 때문

🤔 변수 user에 저장된 객체의 구조를 그대로 타입으로 만들려면 어떻게 해야 할까? 

 

2️⃣ 객체 리터럴 타입

중괄호를 열고 객체가 갖는 프로퍼티를 직접 내열해 만드는 타입

let user: {
  id: number;
  name: string;
} = {
  id: 1,
  name: "kim",
};

user.id; //오류x

 

😀 타입스크립트의 구조적 타입 시스템

  • 타입스크립트는 기존의 정적 타입 언어(C, JAVA)와 달리, 객체의 타입을 정의할 때 프로퍼티를 기준으로 객체의 구조를 정의하듯이 타입을 정의한다.
  • 객체에 어떤 프로퍼티가 있어야 하는지 정의하는 방식으로 객체의 타입을 정의한다.

✅ 특수한 프로퍼티 정의하기

선택적 프로퍼티(Optional Property)

특정 프로퍼티를 상황에 따라 생략하도록 만들고 싶다면

해당 프로퍼티 이름 뒤에 `?`를 붙여 선택적 프로퍼티로 만들어 주면 된다. 

let user: {
  id?: number; // 선택적 프로퍼티가 된 id
  name: string;
} = {
  id: 1,
  name: "kim",
};

user = {
  name: "lee",
};

 

읽기전용 프로퍼티(Readonly Property)

특정 프로퍼티를 읽기 전용으로 만들고 싶다면 프로퍼티의 이름 앞에 `readonly` 키워드를 붙이면 된다.

let user: {
  id?: number;
  readonly name: string; // name은 이제 Readonly 프로퍼티가 되었음
} = {
  id: 1,
  name: "kim",
};

user.name = "dskfd"; // 오류 발생

 

 

4. 타입 별칭과 인덱스 시그니쳐

  • 타입 별칭: 변수처럼 타입 정의를 할 수 있게 해주는 문법
  • 인덱스 시그니쳐: 객체 타입을 좀 더 유연하게 정의하도록 도와주는 문법

✅ 타입 별칭(Type Alias)

type User = {
  id: number;
  name: string;
  nickname: string;
  birth: string;
  bio: string;
  location: string;
};

// type User = {} 동일 스코프에 동일한 이름의 타입 별칭 선언 불가
  • 변수를 선언하듯 타입을 별도로 정의할 수 있다.
  • `type 타입이름 = 타입` 형태로 타입을 정의한다.
  • 동일한 스코프에 동일한 이름의 타입 별칭을 선언하는 것은 불가능하다.(변수와 동일)
  • 타입별칭은 컴파일하면 사라진다.

인덱스 시그니처(Index Signature)

객체 타입을 유연하게 정의할 수 있도록 돕는 특수한 문법

type CountryCodes = {
  Korea: string;
  UnitedState: string;
  UnitedKingdom: string;
  // (... 약 100개의 국가)
  Brazil : string
};

let countryCodes: CountryCodes = {
  Korea: "ko",
  UnitedState: "us",
  UnitedKingdom: "uk",
  // (... 약 100개의 국가)
  Brazil : 'bz'
};

위와 같이 국가들의 영어 코드를 저장하는 객체가 있다고 가정했을 때,

100개의 프로퍼티를 추가하면 타입 정의에도 각 프로퍼티를 모두 정의해 주어야 한다.

이 경우 코드가 매우 길어지고 코드 작성에 불편함을 겪을 수 있다.

이럴 때 인덱스 시그니쳐를 사용하면 간단하게 타입 정의가 가능하다.

type CountryCodes = {
  [key: string]: string;
};

let countryCodes: CountryCodes = {
  Korea: "ko",
  UnitedState: "us",
  UnitedKingdom: "uk",
  // (... 약 100개의 국가)
  Brazil : 'bz'
};

`[key:string]: string`: 이 객체 타입에는 key가 string 타입이며 value가 string 타입인 모든 프로퍼티가 포함된다는 의미의 인덱스 시그니쳐 문법.

 

type CountryCodes = {
  [key: string]: string;
  Korea: string; //반드시 포함해야 하는 프로퍼티가 있다면 직접 명시도 가능
  //korea: number; //불가!
};

let countryCodes: CountryCodes = {
  Korea: "ko",
  UnitedState: "us",
  UnitedKingdom: "uk",
  // (... 약 100개의 국가)
  Brazil : 'bz'
};

반드시 포함해야 하는 프로퍼티가 있다면 `Korea: string;`처럼 직접 타입을 명시할 수도 있다.

 

🚫 주의 🚫

인덱스 시그니쳐를 사용하면서 추가적으로 프로퍼티를 명시할 때는

인덱스 시그니쳐의 value 타입과 직접 추가한 프로퍼티의 value 타입이 호환되거나 일치해야 한다.

 

 

5. 열거형 타입

✅ 열거형(Enum) 타입

  • 자바스크립트에는 존재하지 않음 👉 타입스크립트에서만 사용 가능한 특별한 타입
  • 여러 개의 값을 나열하는 용도로 사용
enum Role {
  ADMIN,
  USER,
  GUEST,
}
//enum 각 멤버에 숫자 할당 가능
enum Role {
  ADMIN = 0,
  USER = 1,
  GUEST = 2,
}

const user1 = {
  name: "kim",
  role: Role.ADMIN, //관리자
};

const user2 = {
  name: "lee",
  role: Role.USER, // 회원
};

const user3 = {
  name: "park",
  role: Role.GUEST, // 게스트
};
  • user1.role에는 0, user2.role에는 1, user3.role에는 2가 할당된다. 
  • 유저의 권한과 같은 여러 개의 멤버를 갖는 값을 숫자로 표기할 때 enum을 사용하면 보다 안전하고 직관적인 데이터 관리가 가능하다.
  • enum 멤버에 숫자 값을 할당하지 않으면 기본적으로 0부터 1씩 늘어나며 자동으로 값이 할당된다.
  • 만약 특정 숫자부터 값을 할당하고 싶다면 시작 숫자를 직접 할당해 주면 된다.
enum Role {
  ADMIN = 10, // 10 할당 
  USER,       // 11 할당(자동)
  GUEST,      // 12 할당(자동)
}

const user1 = {
  name: "kim",
  role: Role.ADMIN, // 10
};

const user2 = {
  name: "lee",
  role: Role.USER, // 11
};

const user3 = {
  name: "park",
  role: Role.GUEST, // 12
};

이렇게 멤버의 값이 모두 숫자인 enum을 숫자형 enum 혹은 숫자 열거형 타입이라 한다.

 

✅ 문자열 열거형

enum Language {
  korean = "ko",
  english = "en",
}
  • enum의 멤버에 문자열 값을 할당할 수도 있다.
  • 모든 멤버의 갑싱 문자열 값인 enum을 자열 enum이라고 부른다.
  • 숫자형 enum과 동일하게 프로퍼티의 값으로 사용가능하다.
enum Role {
  ADMIN,
  USER,
  GUEST,
}

enum Language {
  korean = "ko",
  english = "en",
}

const user1 = {
  name: "kim",
  role: Role.ADMIN, // 0
  language: Language.korean,// "ko"
};

문자열 enum을 사용하면 user1.language 같은 프로퍼티에 "ko"를 "kos"와 같이 작성하는 오타를 낸다거나 값을 헷갈려 다른 문자열을 적어 넣는 등의 실수를 방지할 수 있다.

 

✅ enum은 컴파일 결과 객체가 된다.

enum은 컴파일 시 다른 타입들처럼 사라지지 않고 자바스크립트 객체로 변환된다.

var Role;
(function (Role) {
    Role[Role["ADMIN"] = 0] = "ADMIN";
    Role[Role["USER"] = 1] = "USER";
    Role[Role["GUEST"] = 2] = "GUEST";
})(Role || (Role = {}));
var Language;
(function (Language) {
    Language["korean"] = "ko";
    Language["english"] = "en";
    Language["japanese"] = "jp";
})(Language || (Language = {}));
const user1 = {

 

 
 

출처

반응형