[TypeScript] 인터페이스

Yeojin Choi·2021년 11월 30일
0

Typescript

목록 보기
2/2

객체 타입 정의

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 이재승

profile
프론트가 좋아요

0개의 댓글