반응형

 

 

https://www.udemy.com/course/react-typescript-the-practical-guide/

위 Udemy 강좌에서 배운 내용을 정리하면서, 더 깊은 이해를 위해 내가 따로 조사한 내용도 같이 작성한다.

 

1. Custom Type

아래 calcFn을 보면 type 정의가 다소 길다는 게 보인다.

function calculate(
  a: number,
  b: number,
  calcFn: (a: number, b: number) => number
) {
  calcFn(a, b);
}

type 키워드를 사용하면 Custom type(= type alias)를 만들 수 있다(즉 어떤 type에 대해 alias(= custom name)를 부여하는 것).

type 키워드는 JavaScript가 아닌 TypeScript에만 고유하다.

type AddFn = (a: number, b: number) => number; // type에 AddFn이라는 alias를 준다. AddFn은 이제 Custom Type.
function calculate(
  a: number,
  b: number,
  calcFn: AddFn
) {
  calcFn(a, b);
}

이렇게 만든 custom type은 다른 곳에서도 재활용이 가능하다.

 

Custom type은 function 말고도 다른 데서도 사용 가능하다.

  • union 타입에도 적용 가능.
type StringOrNum = string | number;
  • object 타입에도 적용 가능.
type User = {
  name: string;
  age: number;
  isAdmin: boolean;
  id: string | number;
};

 

 

2. Interface

Object의 type을 정의하는데는 custom type뿐 아니라 interface를 사용할 수도 있다.

interface 키워드도 JavaScript가 아닌 TypeScript에만 고유하다.

interface Credentials {
  password: string;
  email: string;
}

사실 interface는 보통 Object 타입의 정의를 위해서만 사용된다.

(function 타입에도 가능은 하지만 사용되지 않는다. 반면 custom type에선 가능했던 union 타입에는 사용불가하다.)

실제 변수는 아래처럼 사용하면 된다.

let creds: Credentials;

creds = {
  password: "abc",
  email: "test@example.com",
};

 

 

3. Custom type vs Interface

그러면 Object 타입을 정의하는데 custom type만 쓰면 되지 interface는 굳이 또 왜 있는 건가?

두 가지는 사용법이 어떻게 다른 걸까?

 

Interface는 몇가지 장점이 있다.

 

1) interface를 implement하는 class를 선언할 수 있다.

해당 class는 interface에 정의된 property와 method를 반드시 포함해야 한다(즉 interface는 class가 준수해야 하는 계약).

class AuthCredentials implements Credentials {
  email: string;	// 반드시 implement되야 함.
  password: string;	// 반드시 implement되야 함.
  userName: string;	// class가 별도로 property 추가 가능.
}

아래와 같이 inteface 타입을 인자로 받는 함수는 이제 위 class 타입도 받을 수 있다.

function login(credentials: Credentials) {}

login(creds);

login(new AuthCredentials()); // new로 생성된 object는 interface가 요구하는 property와 method를 모두 갖는 object

따라서 class를 사용하는 프로젝트를 만들고 있다면, 위 강제 기능 덕분에 inteface를 custom type 대신 사용할 만하다.

 

2) interface는 쉽게 extend할 수 있다.

같은 이름의 interface를 redefine해서 추가적인 property와 method를 선언할 수 있다.

이를 Declaration Merging이라고 한다.

interface Credentials {
  password: string;
  email: string;
}

// Declaration Merging을 위해 interface를 사용.
interface Credentials {
  mode: string;
}

굳이 왜 위처럼 해야 하나?

만약 다른 개발자들에게 공유할 library를 짜는 중이고, 해당 library에 interface가 있다고 했을 때, 다른 개발자들도 쉽게 그 interface를 extend하는 것을 허용하고자 한다면?

위의 declaration merging을 통해 추가적인 작업 없이 쉽게 할 수 있다.

즉 declaration merging 기능 덕분에 interface를 custom type 대신 사용할 만하다.

 

위 1)과 2) 의 기능이 필요한 것이 아니라면, custom type이든 interface든 선호하는 것을 사용하면 된다.

반응형

+ Recent posts