반응형

인터페이스

 

인터페이스 (Interface)

상호간에 정의한 규칙, 약속을 의미하며, 변수, 함수, 클래스에 타입을 체크하기 위해 사용한다.

정의된 인스턴스는 직접 생성될 수 없는 추상클래스이며, 인스턴스 내에 정의된 메소드 역시 추상메소드이다.

ES6는 인터페이스를 지원하지 않지만 타입스크립트는 인터페이스를 지원한다.

 

 

인터페이스를 사용하는 이유

프로젝트 외부에서 사용하는 코드의 계약을 정의하는 강력한 방법이다.

타입의 이름을 짓고 코드 안의 계약을 정의한다.

  • 객체의 스펙 (속성과 속성의타입)
  • 함수의 파라미터
  • 함수의 스펙(파라미터, 반환타입)
  • 배열과 객체에 접근하는 방식
  • 클래스

 

인터페이스 예제

// 인터페이스의 정의
interface Todo {
  id: number;
  content: string;
  completed: boolean;
}

// 변수 todo의 타입으로 Todo 인터페이스를 선언하였다.
let todo: Todo;

// 변수 todo는 Todo 인터페이스를 준수하여야 한다.
todo = { id: 1, content: 'typescript', completed: false };

인터페이스에서 정의한 프로퍼티 값을 누락하거나, 정의하지 않은 값을 인수로 전달(초과 프로퍼티)하면

타입스크립트에서는 컴파일 에러가 발생한다. 즉, 인터페이스는 타입을 체크하기 위해 사용된다.

 

 

 


Properties 프로퍼티

 

 

 

인터페이스의 Properties 프로퍼티

1. 컴파일러는 프로퍼티의 두가지 요소를 검사한다.

  • 필수요소 프로퍼티의 유무
  • 프로퍼티의 타입

2. 예약어로 프로퍼티를 세밀하게 컨트롤할 수 있다.

  • ? (Optional Properties)  : 인터페이스의 프로퍼티는 반드시 구현되어야 하지만, ?를 이용한 선택적 프로퍼티로 선언된 경우에는 생략하여도 에러가 발생하지 않는다.
interface SquareConfig {
  color?: string;
  width?: number;
}
 
function createSquare(config: SquareConfig): { color: string; area: number } {
  let newSquare = { color: "white", area: 100 };
  if (config.color) {
    newSquare.color = config.color;
  }
  if (config.width) {
    newSquare.area = config.width * config.width;
  }
  return newSquare;
}
 
let mySquare = createSquare({ color: "black" });
  • readonly(Readonly properties) : 프로퍼티 이름 앞에 readonly 키워드를 붙이면, 객체가 처음 생성될 때만 값을 설정할 수 있고 그 이후 재할당이 불가능하다. 
interface Point {
  readonly x: number;
  readonly y: number;
}

let p1: Point = { x: 10, y: 20 };
p1.x = 5; // error!

 

 

 

 


인터페이스 타입

 

함수, 클래스 인터페이스

타입스크립트에서 인터페이스는 함수, 클래스에서 사용이 가능하다.

 

함수의 타입을 지정하는 인터페이스

올바른 함수의 타입검사를 위해 아래와 같이 사용할 수 있다. 매개변수의 이름은 같을 필요 없다.

// 입력 인자는 string, string  출력 인자는 boolean 임을 지정하는 함수 인터페이스
interface SearchFunc {
    (source: string, subString: string): boolean;
}
// 함수의 타입을 함수인터페이스로 지정함.
let mySearch: SearchFunc;

// 입력값과 출력값의 형식은 인터페이스와 동일해야 한다.
mySearch = function(src: string, sub: string): boolean {
    let result = src.search(sub);
    return result > -1;
}

 

클래스의 타입을 지정하는 인터페이스

클래스가 특정 통신 프로토콜을 충족하도록 명시적으로 강제한다.

// 날짜형태의 프로퍼티가 1개 있는 인터페이스
interface ClockInterface {
    currentTime: Date;
    setTime(d: Date): void; // 추상메서드로 인터페이스를 상속받은 클래스에서 정의되어야 함.
}

// 인터페이스를 상속받은 클래스는 반드시 인터페이스 내에 있는 프로퍼티+메서드를 포함한다.
class Clock implements ClockInterface {
    currentTime: Date = new Date();
    
    setTime(d: Date) {
        this.currentTime = d;
    }
    constructor(h: number, m: number) { }
}

 

 

인터페이스 확장

클래스처럼 인터페이스가 인터페이스를 상속받아 확장할 수 있다.

상속받은 인터페이스가 여러개이면, 각 인터페이스들의 속성값들을 모두 포함하여 선언해야 한다.

interface Shape {
    color: string;
}

// 인터페이스가 인터페이스를 상속받음
interface Square extends Shape {
    sideLength: number;
}

let square = {} as Square;
square.color = "blue";
square.sideLength = 10;
interface Shape {
    color: string;
}

interface PenStroke {
    penWidth: number;
}

// 인터페이스가 인터페이스 여러개를 상속받음
interface Square extends Shape, PenStroke {
    sideLength: number;
}

let square = {} as Square;
square.color = "blue";
square.sideLength = 10;
square.penWidth = 5.0;

 

하이브리드 타입

자바스크립트의 유연하고 동적인 타입특성에 따라 인터페이스 역시 여러가지 타입을 조합할 수 있다.

함수타입이면서 객체타입을 정의할 수 있는 인터페이스를 구현할 수 있다.

interface Counter {
    (start: number): string;
    interval: number;
    reset(): void;
}

function getCounter(): Counter {
    let counter = (function (start: number) { }) as Counter;
    counter.interval = 123;
    counter.reset = function () { };
    return counter;
}

// c는 함수타입을 수행하기도 하고, 객체타입을 수행하기도 한다.
let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;

 


인터페이스를 활용한 디자인패턴

전략 패턴

객체가 할 수 있는 행위들을 전략으로 만들어 두고, 

동적으로 행위의 수정이 필요한 경우 전략을 바꾸는 것만으로 수정이 가능하도록 만드는 패턴이다.

 

즉, 자판기 결제 방법을 전략(현금결제, 카드결제... 등)으로 만들어두고, 결제방식의 수정이 필요한 경우 전략을 바꾸는 것만으로 수정이 가능해진다.

 

- 결제전략에 필요 메서드를 포함한 인터페이스

interface PaymentStrategy {
  pay(): void;
}

 

- 결제 방식에 따른 전략을 클래스로 정의 ( 인터페이스의 추상메서드는 여기서 구현되어져야 함) 

- 자판기 클래스 생성. 전략을 주입하는 setPaymentStrategy 메서드를 정의한다.

- 추후 결제전략이 바뀔 경우, 이 메서드를 이용해 전략을 바꾸면 된다.

class VendingMachine {
  private paymentStrategy: PaymentStrategy;

  // 전략 변경 메서드
  setPaymentStrategy(paymentStrategy: PaymentStrategy) {
    this.paymentStrategy = paymentStrategy;
  }

  // 바뀐 전략에 따라 호출되는 메서드도 달라짐.
  pay() {
    this.paymentStrategy.pay();
  }
}

 

- 자판기 선언 후 현금결제 전략 주입 후 출력해보고, 카드결제 전략 주입 후 출력해보기

const vendingMachine = new VendingMachine();

vendingMachine.setPaymentStrategy(new CashPaymentStrategy());
vendingMachine.pay(); // cash pay

vendingMachine.setPaymentStrategy(new CardPaymentStrategy());
vendingMachine.pay(); // card pay

 

 

 

 

 

참고

https://poiemaweb.com/typescript-interface

 

TypeScript - Interface | PoiemaWeb

인터페이스는 일반적으로 타입 체크를 위해 사용되며 변수, 함수, 클래스에 사용할 수 있다. 인터페이스는 여러가지 타입을 갖는 프로퍼티로 이루어진 새로운 타입을 정의하는 것과 유사하다.

poiemaweb.com

 

https://typescript-kr.github.io/pages/interfaces.html

 

TypeScript 한글 문서

TypeScript 한글 번역 문서입니다

typescript-kr.github.io

 

반응형

+ Recent posts