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든 선호하는 것을 사용하면 된다.
'JavaScript&TypeScript' 카테고리의 다른 글
[JavaScript] Document Object Model(DOM) (2) | 2024.12.26 |
---|---|
[JavaScript] Browser Object Model(BOM) (0) | 2024.12.23 |
[TypeScript] JavaScript vs TypeScript 및 TypeScript 설치방법 (0) | 2023.11.26 |