인터페이스

📘 쉽게 시작하는 타입스크립트 스터디

🚀 인터페이스

타입스크립트에서 인터페이스는 객체 타입을 정의할 때 사용하는 문법이다.

📌 인터페이스를 이용한 객체 타입 정의

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 속성이 무조건 들어간다고 한다면 섞어서 정의할 수도 있다.
이처럼 객체의 속성 이른과 속성 값이 정해져 있는 경우에는 속성 이름과 속성 값 타입을 명시해서 정의하고, 속성 이름은 모르지만 속성 이름의 타입과 값의 타입을 아는 경우에는 인덱스 시그니처를 활용한다.