Interface

beomjin_97·2022년 12월 15일
0

typescript

목록 보기
4/7

1. Interface

  • 직접 인스턴스를 생성할 수 없고 모든 메서드가 추상메서드이다.
  • 타입의 이름을 짓고 코드 안의 계약을 정의한다.
    • 객체의 스펙 (속성, 속성의 타입)
    • 함수의 스펙 (파라미터, 반환 타입)
    • 함수의 파라미터
    • 배열과 객체에 접근하는 방식
    • 클래스
interface Person {
  name: string
}

function sayName(obj: Person) {
  console.log(obj.name)
}

let person = {name: "beomjin"}
sayName(person)

2. properties

typescript 컴파일러는 필수요소 프로퍼티의 유무와 그 프로퍼티의 타입을 검사한다.

2.1 optional properties

  • 이름 끝에 ?를 붙여 사용한다.
  • 해당 프로퍼티가 없어도 type 에러가 발생하지 않는다.
  • interface에 속하지 않는 프로퍼티의 사용을 방지함과 동시에, 사용 가능한 프로퍼티를 기술 할 때 사용한다.
interface User {
  name: string;
  age?: number;
}

function createUser(userData: User): { name: string; age: number | null } {
  return {
    name: userData.name,
    age: userData.age ? userData.age : null,
  };
}

2.2 readonly properties

  • 객체가 처음 생성될 때만 값 설정이 가능하고 이후 수정이 불가능하다.
interface Point {
  readonly x: number;
  readonly y: number;
}

let point: Point = { x: 10, y: 20 };

point.x = 1; // Error : Cannot assign to 'x' because it is a read-only property.

3. Utilization

3.1 function

함수의 타입을 정의할 수 있다.

interface SearchFunc {
  (source: string, subString: string): boolean;
}

let search: SearchFunc = function (src, sub) {
  let result = src.search(sub);
  return result > 1;
}

3.2 class

클래스가 특정 계약을 충족하도록 명시한다.

interface Animal {
  makeSound(): void;
}

class Dog implements Animal {
  makeSound(): void {
    console.log("bark bark");
  }
}

3.3 interface 확장

인터페이스간 확장이 가능하다.

interface Animal {
  makeSound(): void;
}

interface Dog extends Animal {
  speed: number;
}

class Bulldog implements Dog {
  speed: 10;
  makeSound(): void {
    console.log("bark bark");
  }
}

3.4 hybrid type

일반적이진 않지만 자바스크립트는 유연하고 동적인 타입 특서을 갖기 때문에 함수와 객체 역할 모두 수행하는 객체를 가질 수도 있다. 이 때에도 hybrid type을 이용해 타입을 기술할 수 있다.

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;
}

let c = getCounter();
console.log(c);

4. interface를 활용한 디자인 패턴

결제 방식에 따라 pay 메서드를 변경하지 않고 전략 패턴을 변경한다.
다음 코드는 OCP(Open Closed Principle)를 위반하지 않고 문제를 해결하는 예시이다.

interface PaymentStrategy {
  pay(): void;
}

// PaymentStrategy를 상속받는 두 개의 클래스를 구현해주세요.
// 각 클래스의 `pay()` 메소드를 호출했을 때 cash pay, card pay가 출력되어야 합니다.
class CardPaymentStrategy implements PaymentStrategy {
  pay(): void {
    console.log("card pay");
  }
}

class CashPaymentStrategy implements PaymentStrategy {
  pay(): void {
    console.log("cash pay");
  }
}

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
profile
Rather be dead than cool.

0개의 댓글