인터페이스
타입스크립트에서 인터페이스는 객체 타입을 정의할 때 사용하는 문법이다.
interface User {
name: string;
age: number;
}
var seho: User = { name: '세호', age: 36 };
인터페이스라는 예약어를 이용하여 User라는 인터페이스를 선언한 코드이다.
인터페이스 속성으로 name과 age를 각각 문자열과 숫자 타입으로 정의했다.
객체의 속성과 들어갈 데이터 타입을 정의하게 정의할 수 있다.
객체가 활용되는 모든 곳에 인터페이스를 쓸 수 있다.
객체는 함수의 파라미터로도 사용되고 반환값으로도 사용될 수 있다.
interface Person {
name: string;
age: number;
}
function logAge(someone: Person) {
console.log(somenone.age);
}
var captain = {name: 'Capt', age: 100};
logAge(captain); //100
logAge()는 somenone이라는 인자를 받아 인자 안의 age 속성을 출력하는 간단한 함수이다.
이 코드는 Person이라는 인터페이스를 선언한 후 logAge() 함수의 파라미터인 someone에 Person 타입을 정의한다.
이름이 Capt이고 나이는 100인 객체를 captain이라는 변수에 할당하고 logAge() 함수에 넘긴 인자가 파라미터 타입을 만족하기 때문에 에러 없이 실행된다.
getPerson() 함수는 person 인터페이스 타입의 데이터를 받아 그대로 반환해 주고 있다.
이 함수의 반환 타입을 명시적으로 표시하기 위해 다음과 같이 인터페이스로 함수의 반환 타입을 정의할 수 있다.
interface Person {
name: string;
age: number;
}
function getPerson(someone: Person) {
return someone;
}
var hulk = getPerson({ name: 'hulk', age: 99 });
getPerson() 함수의 호출 결과를 변수에 할당하면 다음과 같이 해당 변수가 Person 인터페이스 타입으로 추론된다.
interface Person {
name?: string;
age: number;
}
속성을 2개 가진 객체에서 속성 1개만 필요할 때가 있다.
이때 사용할 수 있는 것이 옵션 속성(optional property) 이다.
상속은 객체 간 관계 형성하는 방법이며, 상위 클래스의 내용을 하위 클래스가 물려받아 사용하거나 확장하는 기법을 의미한다.
클래스를 상속받을 때 extends란 예약어를 사용했다. 인터페이스를 상속받을 때도 동일하게 extends 예약어를 사용한다.
interface Person {
name: string;
age: number;
}
interface Developer extends Person {
skill: string;
}
var ironman: Developer = {
name: '아이언맨',
age: 21,
skill: '만들기'
}
Person 인터페이스를 선언하고 Developer 인터페이스에 extends로 상속한 것이다.
이렇게 extends 키워드를 사용해서 인터페이스의 타입을 상속받아 확장하여 사용할 수 있고 여러번 상속을 받아서 정의할 수 있다.
var user = {
name: '캡션',
admin: true
}
console.log(user['name']); //캡션
var companies = ['삼성', '네이버', '구글'];
console.log(companies[0]); //삼성
user['name']
형태로 객체의 특정 속성에 접근하거나 companies[0]
형태로 배열의 특정 요소에 접근하는 것을 인덱싱이라고한다.
interface StringArray {
[index: number]: string;
}
var companies = ['삼성', '네이버', '구글'];
StringArray 인터페이스의 속성의 [index: number]
가 어떤 숫자든 모두 속성의 이름이 될 수 있다는 의미이다.
[index: number]: string;
에서 속성 이름은 숫자고 그 속성 값으로 문자열 타입이 와야한다는 의미이다.
배열의 인덱스가 0이 될 수도 있고 99, 2000 등 어떤 숫자든 될 수 있기때문에 [index: number]
로 정의 한다.
companies[0]; //삼성
companies[2]; //구글
interface SalaryMap {
[level: string]: number;
}
var salary: SalaryMap = {
junior: 100
};
var money = salary['junior'];
이 SalaryMap 인터페이스는 속성 이름이 문자열 타입이고 속성 값이 숫자인 타입인 모든 속성 이름/속성 값 쌍을 허용하겠다는 의미이다. 객체의 속성에 접근하는 방법은 salary['junior']
또는 salary.junior
모두 가능하다.
다만 속성 이름에 숫자나 - 등 특수 기호가 들어가면 .junior 방식으로 접근할 수 없기 때문에 salary['junior']
방식으로 접근해야한다.
이처럼 정확히 속성 이름을 명시하지 않고 속성 이름의 타입과 속성 값의 타입을 정의하는 문법을 인덱스 시그니처(index signature) 라고 한다.
interface SalaryMap {
[level: string]: string;
}
var salary: SalaryInfo = {
junior: '100원',
mid: '400원',
senior: '700원',
ceo: '0원',
newbie: '50원',
};
단순히 객체와 배열을 인덱싱 할 때 활용될 뿐만 아니라 객체의 속성 타입을 유연하게 정의할 때도 사용된다.
속성 이름이 문자열이고 속성 값의 타입이 문자열이기만 하면 1개든 100개든 모두 추가할 수 있는 장점이 생긴다.
interface User {
[property: string]: string;
id: string;
name: string;
}
var seho: User = {
id: '1',
name: '세호',
address: '판교'
};
User라는 인터페이스에는 id와 name 속성이 무조건 들어간다고 한다면 섞어서 정의할 수도 있다.
이처럼 객체의 속성 이른과 속성 값이 정해져 있는 경우에는 속성 이름과 속성 값 타입을 명시해서 정의하고, 속성 이름은 모르지만 속성 이름의 타입과 값의 타입을 아는 경우에는 인덱스 시그니처를 활용한다.