interface
키워드를 사용해 객체의 타입을 정의할 수 있다.
//interface 정의
interface Person {
name:string; // 객체 내부의 각 속성 타입 정의
age: number;
}
const p1: Person = {name: 'mike', age: 23};
const p2: Person = {name: 'mike', age: '23'}; // age 속성 타입을 만족하지 못해 type error 발생
물음표 기호를 사용하여 객체에서 없어도 되는 속성을 지정할 수 있다.
interface Person {
name:string;
age?: number;
}
const p1: Person = {name: 'mike'};
하지만 물음표 기호를 사용하지 않고 undefined 를 유니온 타입으로 추가하면 명시적으로 age 속성을 입력해야한다.
interface Person {
name:string;
age: number | undefined;
}
const p1: Person = {name: 'mike'}; // type error
const p2: Person = {name: 'mike', age: undefined};
readonly
키워드를 사용해 값이 변하지 않는 속성을 정의할 수 있다.
interface Person {
readonly name:string;
age?: number;
}
const p1: Person = {name: 'mike'}; // 변수 정의하는 시점에는 값을 할당할 수 있다.
p1.name = 'John'; // 읽기 전용 속성의 값을 수정하려 했기 때문에 compile error 발생
interface Person {
name:string;
age?: number;
}
const p1 = {name: 'mike', birthday: '1994-12-09'};
// 리터럴로 값을 초기화 할 경우
const p2: Person = {name: 'mike', birthday: '1994-12-09'};
//birthday 속성이 정의되어 있지 않기 때문에 type error 발생
const p3: Person = p2;
// p3 객체가 p2의 타입을 포함하는 더 큰 타입이기 때문에 type error가 발생하지 않는다.
인덱스 타입: 인터페이스에서 속성 이름을 구체적으로 정의하지 않고 값의 타입만 정의하는 것
interface Person {
name:string;
age: number;
[key:string]: string | number; // 문자열로 된 모든 속성 이름에 대해 값이 문자열 또는 숫자라고 정의
}
const p1: Person = {
name: 'mike';
age: 23;
birthday: '1994-12-09'; // type error 발생 X
}
javascript
에서는 속성 이름에 숫자, 문자열을 사용할 수 있다. (숫자를 사용할 경우 문자열로 변환된 후 사용된다)typescript
에서는 속성 이름의 값이 숫자일 경우, 문자열인 속성 이름의 값으로 할당 가능한지 검사한다.속성 이름의 타입으로 숫자와 문자열을 동시에 사용한 경우
interface YearPriceMap {
[year: number]: A;
[year: string]: B; //A type 은 B type 에 할당 가능해야 한다!
}
여러 개의 인덱스를 정의해서 사용하기
interface YearPriceMap {
[year: number]: number;
[year: string]: string | number;
}
const yearMap: YearPriceMap = {};
yearMap[2000] = 1000;
yearMap[2000] = 'abc'; // interface 속성 이름이 숫자인데 문자열을 할당하려고 했기 때문에 type error 발생
yearMap['2000'] = 1234;
yearMap['2000'] = 'million';
implements
키워드를 사용해 인터페이스를 클래스로 구현할 수 있다.
이때, 인터페이스에서 정의한 모든 속성을 구현하여야 한다.
interface Person {
name:string;
age: number;
isYoungerThan(age: number): boolean;
}
class SomePerson implements Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
isYoungerThan(age: number) {
return this.age < age;
}
}
extends
키워드를 사용하여 기존의 인터페이스를 확장해 새로운 인터페이스를 만들 수 있다.
interface Person {
name:string;
age: number;
isYoungerThan(age: number): boolean;
}
//Person interface 를 확장해 Korean interface 의 생성
interface Korean extends Person {
isLiveInSeoul: boolean;
}
/*--여러 개의 인터페이스 확장--*/
interface Programmer {
favoriteProgrammingLanguage: string;
}
//Person, Programmer interface를 확장해 KoreanProgrammer interface 생성
interface KoreanProgrammer extends Person, Programmer {
isLiveInSeoul: boolean;
}
교차 타입 (= intersection. & 연산자) 을 이용해 여러 인터페이스를 하나로 합칠 수 있다.
interface Person {
name:string;
age: number;
}
interface Product {
name:string;
price: number;
}
type PP = Person & Product;
const pp: PP = { // 합쳐진 두 인터페이스 Person, Product 의 모든 속성들을 포함한다
name: 'a',
age: 23,
price: 1000
}
참고 : 실전 리액트 프로그래밍 개정판 by 이재승