TypeScript

[TypeScript]객체(Object) 타입 정의

DevStory 2021. 9. 13.

타입스크립트(TypeScript)는 자바스크립트(JavaScript)에 비해 타입을 엄격하게 처리하므로 변수 또는 객체를 선언할 때, 타입을 정의해야 합니다.

 

객체의 타입을 정의하는 방법은 interfacetype이 존재하는데, 대부분의 TypeScript 개발자들은 확장성이 좋은 interface 사용을 권장합니다.

 

하지만, 타입이 심플하거나 절대 변경되지 않는 경우에는 type을 사용하여 객체의 타입을 정의하기도 합니다.

 

이번 포스팅에서는 interface와 type을 사용하여 객체의 타입을 정의하는 방법 그리고 중첩된 객체의 타입을 정의하는 방법을 정리하였습니다.


일반 객체 타입 정의

object는 interface, class의 상위 타입입니다. Java에서 최상위 클래스가 Object 클래스인 것처럼 JavaScript에서 최상위 객체는 object입니다.

let obj: object = { name: 'NAME', age: 29 };

obj = { A: 'A', B: 'B' };

타입을 object로 정의하면, any 타입처럼 모든 타입의 값을 할당할 수 있습니다.

 

객체를 object 타입으로 정의하는 경우 타입 검사에 엄격한 TypeScript를 사용한 목적이 애매모호해집니다.

 

interface로 구현

객체의 타입을 명확하게 정의하기 위해 interface를 구현할 수 있습니다.

interface IUser {
  name: string,
  age : number
}

let obj: IUser = { name: 'NAME', age: 29 };

name은 문자열(string), age는 숫자형(number) 타입을 가지는 IUser 인터페이스를 구현 후 객체 obj의 타입을 IUser 인터페이스로 정의하였습니다.

 

type으로 구현

객체의 타입은 interface와 유사한 type으로도 구현할 수 있습니다.

type UserType = {
  name: string,
  age : number
}

let obj: UserType = { name: 'NAME', age: 29 };
반응형

interface, type 확장

객체의 타입을 확장해야 하는 경우 interface는 extends 키워드를 사용하며 type은 & 연산자를 사용합니다.

 

단, 이미 정의된 타입을 확장하는 것은 불가능합니다. 

 

interface 확장

아래 코드는 interface를 확장한 코드입니다.

interface IUser {
  name: string;
  age: number;
};

interface INewUser extends IUser { 
  address: string 
};

let obj: INewUser = { name: "NAME", age: 29, address: 'Busan' };

extends 키워드를 사용하여 IUser의 인터페이스를 INewUse로 확장하였습니다. 즉, IUser 인터페이스의 프로퍼티가 INewUser 인터페이스에 복사되었으며, address 프로퍼티를 추가하였습니다.

 

type 확장

아래 코드는 type을 확장한 코드입니다.

type UserType = {
  name: string;
  age: number;
};

type NewUserType = UserType & { address: string };

let obj: NewUserType = { name: "NAME", age: 29, address: 'Busan' };

& 연산자를 사용하여 UserType에 address 프로퍼티 타입 정의가 추가된 NewUserType을 구현하였습니다.


interface 병합

type과 달리 interface는 동일한 interface를 여러 번 정의할 수 있으며, 이때 interface의 프로퍼티는 병합됩니다.

interface IUser {
  name: string
}

interface IUser {
  age: number
}

let obj: IUser = { name: 'NAME', age: 29 };

 

아래 코드처럼 이미 interface를 객체의 타입으로 정의 후 다시 병합하는 경우는 허용되지 않습니다.

interface IUser {
  name: string
}

interface IUser {
  age: number
}

let obj: IUser = { name: 'NAME', age: 29 };


// 객체 obj의 타입을 IUser interface로 정의하였으므로 interface 병합 불가능
interface IUser {
  address: string
}

중첩된 객체(Nested Object) 타입 정의

interface로 중첩된 객체의 타입을 정의하는 방법입니다.

interface Iname {
  first: string;
  last: string;
}

interface IUser {
  name: Iname;
  age: number;
}

let obj: IUser = {
  name: {
    first: "Kang",
    last: "JaeSeong"
  },
  age: 29
};

Iname 인터페이스를 IUser 인터페이스 name 프로퍼티의 타입으로 정의합니다. 즉, 인터페이스 프로퍼티의 타입을 인터페이스로 정의하여 중첩된 객체의 타입을 정의할 수 있습니다.

 

type으로 중첩된 객체의 타입을 정의하는 방법입니다.

type UserType = {
  name : {
    first: string;
    last: string;
  },
  age: number;
}

let obj: UserType = {
  name: {
    first: "Kang",
    last: "JaeSeong"
  },
  age: 29
};

type을 사용하여 중첩된 객체의 타입을 정의하는 경우 여러 개의 type을 작성할 필요가 없으며, 한 번에 정의 가능합니다.

 

하지만, interface가 type에 비해 확장성이 좋기 때문에 interface를 사용하여 객체의 타입을 정의하는 것을 권장합니다.

반응형

댓글