#1. Interface

1. Interface의 개념

1)  Interface란?

  • 인터페이스란 상호간의 정의한 약속 혹은 규칙을 의미한다. 타입스크립트에서의 인터페이스는 특정 자료형의 구조를 규칙으로 정하여 사용하는 것을 말한다.
  • 즉, 객체의 속성이자 구조로 다른 타입과 합치거나 확장 시킬 수 있다.
  • 자바스크립트와 같은 동적타입 언어 환경에서는 없는 기능이지만, 정적타입 언어 환경인 타입스크립트에서는 이를 지원한다.
  • 인터페이스는 자바스크립트로 컴파일 시 제외되어 자바스크립트 파일에서는 확인 할 수 없다.

 

2) Interface 사용 방법

interface 사용할이름 {
  속성1: 타입,
  속성2: 타입,
  .. 타입선언 ..
};
  • interface 키워드 선언 후 객체(object)선언과 비슷하게 선언하고, 타입을 지정해준다.
  • 보통 사용할 이름의 첫 글자는 대문자로 작성한다. (왜그런지는 모르겠으나 선례라고 한다..)
// interface 선언
interface User {
  name: string,
  age: number,
};

// interface를 타입 선언 형식으로 사용
let user: User = {
  name: "ex",
  age: 100,
};
  • 인터페이스에 선언되지 않은 객체 사용시 에러가 발생한다.
// 인터페이스에 선언된 타입
user.age = 10;  // age의 값을 재할당해도 에러가 발생하지 않는다.

// 인터페이스에 선언되지 않은 타입
user.gender = "male";  // 인터페이스에 선언되지 않은 객체이므로 에러

인터페이스에 선언되지 않은 객체는 에러가 발생된다.

 

3) Interface를 사용하는 이유

인터페이스를 사용하지 않고 변수에 object 타입을 선언해서 사용하려고 하면

let user1: object;

user1 = {
  name: 'xx',
  age: 30
};

인터페이스를 사용하지 않고, object 타입으로 선언하여 사용하면 에러가 발생한다.

위 이미지와 같이 name 속성이 object 타입에 없다는 에러가 발생한다.

 

2. Interface 사용하기

1) 선택적 프로퍼티 (Optional Properties)

선택적 프로퍼티를 사용하지 않을 경우,

interface User {
  name: string,
  age: number,
  gender: string
};

let user: User = {
  name: "ex",
  age: 100,
};

  • 인터페이스에서 gender를 선언 했는데, 객체에서 사용하지 않으면 에러가 발생한다.
  • 하지만, 선택적 프로퍼티를 사용하면 gender를 사용하지 않아도 에러가 발생하지 않는다.
interface User {
  gender?: string,  // 옵셔널 프로퍼티
};
  • 인터페이스에서 반드시 포함되지 않아도 되는 속성이 있을 것이다. 구현하는 방법은 속성 뒤에 물음표(?)를 붙여주기만 하면 된다.
  • 이를 사용함으로서, 반드시 필요하지 않은 속성을 구분할 수 있고, 이에 대한 오류도 확인 가능하다.

 

2) 읽기 전용 프로퍼티 (Read-only Properties)

interface User {
  readonly birthYear: number,  // 최초에 생성할 때만 선언 가능 하고 이후 수정은 안됨
};
  • 인터페이스에 속성을 선언할 때, 앞에 readonly만 붙여주면 된다.
  • 최초 생성할 때만 선언 가능 하고 이후 수정은 불가능하다.
let user: User = {
  birthYear: 2000,  // 최초 선언
}

user.birthYear = 1990; // readonly에 수정하면 에러발생

readonly가 선언된 birthday를 재할당 하려면 에러가 발생한다.

 

3) 인덱서블 타입 (Index Signatures(Indexable types))

interface User {
  [key: number]: string,  // 여러개의 key값으로 숫자형이 들어오고 value로 문자열값을 받음
};

let user: User = {
  1: 'A',
  2: 'B',
  3: 'C',
};
  • 인터페이스에 속성과 타입을 일일히 하나하나 지정해주면 활용도가 매우 낮아진다.
  • 그래서 객체, 배열과 같은 경우 속성이 많이 들어가면 [속성: 타입]: 타입 형태인 인덱서블 타입을 사용해 주는 것이 좋다.
  • 이 타입은 string과 number만 지정해 줄 수 있다.

타입에 맞지 않게 선언할 경우 에러 발생

 

4) 함수에 사용하기

interface Add {
  (num1: number, num2: number): number;  // 인터페이스에 파라미터 타입 선언
}
  • 파라미터로 들어올 값의 타입을 선언하고, return 될 값의 타입을 선언한다. (위의 예시는 모두 number)
const add: Add = function(x, y) {  // 파라미터 이름은 다르게 넣어도 된다.
  return x + y;
}
  • 함수 타입 인터페이스를 미리 선언해 두면 함수 선언 시 별도의 타입 설정을 할 필요가 없다.

인터페이스에 선언한 파라미터보다 인자값이 더 많으면 에러 발생
타입이 맞지 않으면 에러 발생

 

5) 클래스 정의

// 인터페이스 정의
interface CarType {
  color: string,
  wheels: number,
  start(): void,
};

// implements를 통해 클래스 선언
class Car implements CarType {  // 인터페이스에 선언된 값을 모두 사용해야 에러가 안난다
  color;

  constructor(color: string) {  // 객체가 생성될 때 값을 받으려면 생성자 선언
    this.color = color
  }
  wheels = 4;
  start() {
    console.log("engine start..");
  }
};

// 객체 생성
const bmw = new Car("green");
console.log(bmw);  // Car { wheels: 4, color: 'green' }
bmw.start();  // engine start..
  • 인터페이스는 클래스와 비슷하지만, 추상 클래스 처럼 정의만 할 뿐 실제 구현되지는 않는다.
  • 클래스는 extends 키워드로 클래스를 상속하고, 인터페이스로 클래스를 정의할 때 는 implements 키워드를 사용해 해당 인터페이스들을 클래스와 연결 시킨다.

implements를 통해 정의된 클래스를 인터페이스에 상속

// extends
interface Benz extends Car {  // Car가 가지고 있던 속성을 그대로 확장(상속)
  door: number;
  stop(): void;
}

// 상속받은 클래스를 통해 선언된 인터페이스 타입 사용
const benz: Benz = { // 상속받은 속성들을 다 사용해줘야 에러 안남
  color: "red",
  wheels: 5,
  door: 5,
  start() {
    console.log("let's go");
  },
  stop() {
    console.log("stop");
  }
};
  • 확장은 클래스에서 인터페이스로도 가능하고, 인터페이스에서 클래스로도 가능하다.
interface Toy {
  name: string,
}

// 한 번에 두개의 인터페이스 상속
interface ToyCar extends CarType, Toy {
  price: number,
}
  • 뿐만 아니라 한번에 여러개의 인터페이스를 동시에 상속받을 수 있다.

'Extend > TypeScript' 카테고리의 다른 글

[TypeScript] 타입 선언하기  (0) 2022.10.03
[TypeScript] TypeScript 사용하기  (0) 2022.10.03

+ Recent posts