타입스크립트의 지향점은 타입 체크는 값의 형태에 기반하여 이루어져야 한다는 점이다. 이를 Duck Typing
또는 Structural Subtyping
이라 한다.
Duck Typing : 객체의 변수 및 메서드의 집합이 객체의 타입을 결정하는 것을 의미
인터페이스를 사용할 때 인터페이스에 정의되어 있는 속성을 모두 사용하지 않아도 된다. 이를 옵션 속성이라 한다..
interface 인터페이스_이름 {
속성?: 타입;
}
interface Pserson {
name: string;
age?: number;
}
function logPerson(obj: Person) {
console.log(obj);
}
const person1 = { name: "Jkun", age 29 };
const person2 = { name: "Lkun" };
logPerson(person1); // { name: "Jkun", age: 29 }
logPerson(person2); // { name: "Lkun" }
옵션 속성의 장점으로 속성을 선택적으로 적용할 수 있으며 인터페이스에 정의되어 있지 않은 속성에 대해서 인지시켜줄 수 있다.
인터페이스로 객체를 처음 생성할 때만 값을 할당하고 그 이후에는 변경할 수 없는 속성을 의미한다.
interface Logger {
readonly log: string;
}
const myLog: Logger = {
log: "Hello, Typescript"
};
myLog.log = "Bye"; // Error
readonly
속성을 통한 인터페이스 객체를 선언하고 나서 수정하려 하면 위와 같이 오류가 발생한다.
타입스크립트는 인터페이스를 이용하면 객체를 선언할 때 좀 더 엄밀한 속성 검사를 진행한다.
interface Person {
name: string;
age?: number;
}
function logPerson(info: Person) {
console.log(info);
}
const me = { name: "Jkun", desc: "안녕하세요" };
logPerson(me); // Error
해당 인터페이스에 인자로 넘어온 me
객체 내 desc
에 대한 속성이 정의되어 있지 않아 오류가 발생한다.
이런 타입 추론을 무시하고자 한다면,
// ...
logPerson(me as Person);
인터페이스 정의하지 않은 속성들은 추가로 사용하고 싶을 때는,
interface Person {
name: string,
age?: number,
[propName: string]: any;
}
인터페이스는 함수의 타입을 정희할 때 사용할 수 있다.
interface login {
(username: string, password: string): boolean;
}
let loginUser: login;
loginUser = function(username: string, password: string) {
console.log("로그인");
return true;
}
interface Person {
name: string;
}
interface Developer extends Person {
skill: string;
}
const fe = {} as Developer;
fe.name = "Jkun";
fe.skill = "TypeScript";
타입 별칭과 인터페이스의 가장 큰 차이점은 타입의 확장 가능 / 불가능 여부이다.
인터페이스는 확장이 가능한 반면에 타입 별칭은 확장이 불가능하다.
따라서, 가능한한 type
보다는 interface
로 선언해서 사용하는 것을 추천한다.