반응형
객체 타입을 정의하는 방법
- 타입 스크립트에서는 2가지 방식으로 객체의 타입을 정의할 수 있다.
object로 정의
// user 의 타입을 객체를 의미하는 object 로 정의
let user: object = {
id: 1,
name: "이정환",
};
- 이렇게 하면 한 가지 문제가 있다.
- 이유는 타입스크립트의 object 타입은 단순 값이 객체임을 표현하는 것 외에는 아무런 정보도 제공하지 않는 타입이기 때문
- 따라서 이 타입은 객체의 프로퍼티에 대한 정보를 전혀 가지고 있지 않다
- 그렇기 때문에 이렇게 프로퍼티에 접근하려고 하면 오류가 발생
- 이럴 땐 obejct 가 아닌 객체 리터럴 타입을 이용해야함.
객체 리터럴 타입
객체 리터럴은 다음과 같이 중괄호를 열고 객체가 갖는 프로퍼티를 직접 나열해 만드는 타입
let user: {
id: number;
name: string;
} = {
id: 1,
name: "이정환",
};
user.id;
- 변수 user의 타입을 number 타입의 id 그리고 string 타입의 name 프로퍼티를 갖는 객체 타입으로 정의
- 이렇듯 객체 리터럴과 비슷한 문법으로 객체 타입을 정의한 타입을 객체 리터럴 타입이라고 부른다.
선택적 프로퍼티(Optional Property)
- JS 에서 객체를 다루다보면 특정 프로퍼티는 있어도 되고 없어도 되는 상황이 존재함
- 예를 들어 다음과 같이 이름은 있지만 아직 id가 없는 유저가 존재할 수도 있음
let user: {
id: number;
name: string;
} = {
id: 1,
name: "이정환",
};
user = {
name: "홍길동", // 오류 발생!
};
이럴 때 선택적 프로퍼티를 설정하려면 프로퍼티 이름뒤에 "?" 를 붙여주면 된다.
let user: {
id?: number; // 선택적 프로퍼티가 된 id
name: string;
} = {
id: 1,
name: "이정환",
};
user = {
name: "홍길동",
};
읽기전용 프로퍼티 (Readonly Property)
특정 프로퍼티를 읽기 전용으로 만들고 싶다면 프로퍼티의 이름 앞에 readonly 키워드를 붙이면 됨.
let user: {
id?: number;
readonly name: string; // name은 이제 Readonly 프로퍼티가 되었음
} = {
id: 1,
name: "이정환",
};
user.name = "dskfd"; // 오류 발생
- name 프로퍼티는 읽기 전용이기 때문에 수정할 수 없음
타입 별칭 (Type Alias)
- 타입 별칭을 이용하면 다음과 같이 변수를 선언하듯 타입을 별도로 정의가 가능
// 타입 별칭
// type 타입이름 = { ... } 로 정의
type User = {
id: number;
name: string;
nickname: string;
birth: string;
bio: string;
location: string;
};
...
이렇게 만든 타입은 변수의 타입을 정의할 때 타입 주석과 함께 사용 가능
type User = {
id: number;
name: string;
nickname: string;
birth: string;
bio: string;
location: string;
};
let user: User = {
id: 1,
name: "이정환",
nickname: "winterlood",
birth: "1997.01.07",
bio: "안녕하세요",
location: "부천시",
};
let user2: User = {
id: 2,
name: "홍길동",
nickname: "winterlood",
birth: "1997.01.07",
bio: "안녕하세요",
location: "부천시",
};
하지만 동일한 스코프에 동일한 이름의 타입 별칭을 선언하는 것은 불가능함
type User = {
id: number;
name: string;
nickname: string;
birth: string;
bio: string;
location: string;
};
type User = {}
스코프가 다르면 중복된 이름으로 여러개의 별칭해도 상관 없음
type User = {
id: number;
name: string;
nickname: string;
birth: string;
bio: string;
location: string;
};
function test() {
type User = string;
}
인덱스 시그니처 (Index Signature)
객체 타입을 유연하게 정의할 수 있도록 돕는 특수한 문법이다
- 다양한 국가들의 영어 코드를 저장하는 객체가 하나 있다고 가정
type CountryCodes = {
Korea: string;
UnitedState: string;
UnitedKingdom: string;
};
let countryCodes: CountryCodes = {
Korea: "ko",
UnitedState: "us",
UnitedKingdom: "uk",
};
- 이 때 countryCodes 에 100개의 국가 코드가 추가 되어야 한다면 타입 정의에도 각 프로퍼티를 모두 정의 해줘야 하기 때문에 불편
type CountryCodes = {
Korea: string;
UnitedState: string;
UnitedKingdom: string;
// (... 약 100개의 국가)
Brazil : 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;
};
let countryCodes: CountryCodes = {
Korea: "ko",
UnitedState: "us",
UnitedKingdom: "uk",
// (... 약 100개의 국가)
Brazil : 'bz'
};
- 만약 국가 코드를 숫자로 보관하는 객체가 하나 더 필요하다면 다음과 같이 정의하면 된다.
type CountryNumberCodes = {
[key: string]: number;
};
- 반드시 포함해야하는 프로퍼티가 있다면 직접 명시도 가능하다.
type CountryNumberCodes = {
[key: string]: number;
Korea: number;
};
- 주의할 점은 인덱스 시그니처를 사용하면서 동시에 추가적인 프로퍼티를 정의할 때
인덱스 시그니처의 value 타입과 직접 추가한 프로퍼티 value 의 타입이 호환하거나 일치해야한다 - 따라서 다음과 같이 서로 호환되지 않는 타입으로 설정하면 오류가 발생
type CountryNumberCodes = {
[key: string]: number;
Korea: string; // 오류!
};
반응형
'Typescript' 카테고리의 다른 글
Typescript | 타입 호환성, 대수타입 (2) | 2024.10.29 |
---|---|
Typescript | void, never (0) | 2024.10.25 |
Typescript | Enum, any, unknown (0) | 2024.10.25 |
Typescript | 배열과 튜플 (1) | 2024.10.24 |
Typescript | 원시, 리터럴 타입 (0) | 2024.10.24 |