[Typescript] Interfaces

Donghee Choi·2024년 6월 29일

typescript

목록 보기
2/2
  1. interface vs. type

Interface

  • Object의 모양을 특정하는데 사용한다.
  • 같은 interface를 작성하면 합성된다.
  • 클래스를 사용하는 방법과 유사하다.
  • 객체지향 프로그래밍처럼 보인다.

type

  • type도 object의 모양을 정해주는데 사용할 수 있다.
  • interface에 비해 좀 더 활용할 수 있는것이 많다.
    1. 오브젝트 모양 설명 2. 타입 alias 3. 타입을 특정한 값으로 만듬
  1. abstract vs. interface

abstract

  • 다른 클래스가 따라야할 설계도를 제시
  • 자바스크립트에는 abstract의 개념이 없다.
  • 자바스크립트에서는 추상 클래스가 일반적인 클래스로 변한다.
abstract class User {
    constructor(
        protected firstName:string,
        protected lastName:string
    ){}
    abstract sayHi(name:string):string
    abstract fullName():string
}

class Player extends User {
    fullName() {
        return `${this.firstName} ${this.lastName}`
    }
    sayHi(name:string){
        return `Hello ${name}. My name is ${this.fullName}`
    }
}

interface

  • 인터페이스는 가볍다.
  • 컴파일하면 자바스크립트에서 사라진다. (파일 크기가 줄어드는 장점)
  • 인터페이스를 상속할때에는 property를 private으로 만들지 못한다.
  • 추상클래스에서는 생성자를 포함할 수 있고 초기화를 처리할 수 있지만, 인터페이스에서는 생성자를 포함할 수 없다.
  • 하나 이상의 인터페이스를 상속받을 수 있다.
interface User {
     firstName:string,
     lastName:string,
     sayHi(name:string):string,
     fullName():string
}

class Player implements User {
    constructor(
        public firstName: string,
        public lastName: string
    ){}

    fullName() {
        return `${this.firstName} ${this.lastName}`
    }
    sayHi(name:string){
        return `Hello ${name}. My name is ${this.fullName}`
    }
}

챌린지 코드

interface IStorage<T> {
  [key: string]: T;
}

abstract class AbstractStorage<T> {
  protected storage: IStorage<T>;
  constructor() {
    this.storage = {};
  }
  abstract setItem(key: string, value: T): void;
  abstract getItem(key: string): T;
  abstract clearItem(key: string): void;
  abstract clear(): void;
}

class LocalStorage<T> extends AbstractStorage<T> {
  setItem(key: string, value: T) {
    this.storage[key] = value;
  }

  getItem(key: string) {
    return this.storage[key];
  }

  clearItem(key: string) {
    delete this.storage[key];
  }

  clear() {
    this.storage = {};
  }
}

const aa = new LocalStorage<string>();
aa.setItem("aa", "bb");
console.log(aa.getItem("aa"));
aa.clearItem("aa");
console.log(aa.getItem("aa"));

interface IOption {
  maximumAge?: number;
  timeout?: number;
  enableHighAccuracy?: boolean;
}

interface IGeolocationCoordinates {
  readonly latitude: number;
  readonly longitude: number;
  readonly altitude: number | null;
  readonly accuracy: number;
  readonly altitudeAccuracy: number | null;
  readonly heading: number | null;
  readonly speed: number | null;
}

interface IGeolocationPosition {
  readonly coords: IGeolocationCoordinates;
  readonly timestamp: DOMHighResTimeStamp;
}

interface IGeolocationPositionError {
  readonly code: number;
  readonly message: string;
}

interface IGeolocation {
  getCurrentPosition(
    successFn: (pos: IGeolocationPosition) => void,
    errorFn?: (err: IGeolocationPositionError) => void,
    optionsObj?: IOption
  ): void;
  watchPosition(
    success: (pos: IGeolocationPosition) => void,
    error?: (err: IGeolocationPositionError) => void,
    options?: IOption
  ): number;
  clearWatch(id: number): void;
}

class MyGeolocation<T> implements IGeolocation {
  getCurrentPosition(
    successFn: (pos: IGeolocationPosition) => void,
    errorFn?: (err: IGeolocationPositionError) => void,
    optionsObj?: IOption
  ): void {
    navigator.geolocation.getCurrentPosition(
      (position) => {
        const geoPosition: IGeolocationPosition = {
          coords: {
            latitude: position.coords.latitude,
            longitude: position.coords.longitude,
            altitude: position.coords.altitude,
            accuracy: position.coords.accuracy,
            altitudeAccuracy: position.coords.altitudeAccuracy,
            heading: position.coords.heading,
            speed: position.coords.speed,
          },
          timestamp: position.timestamp,
        };
        successFn(geoPosition);
      },
      (error) => {
        if (errorFn) {
          errorFn(error);
        }
      },
      optionsObj
    );
  }
  watchPosition(
    success: (pos: IGeolocationPosition) => void,
    error?: (err: IGeolocationPositionError) => void,
    options?: IOption
  ): number {
    const watchId = navigator.geolocation.watchPosition(
      (position) => {
        const geoPosition: IGeolocationPosition = {
          coords: {
            latitude: position.coords.latitude,
            longitude: position.coords.longitude,
            altitude: position.coords.altitude,
            accuracy: position.coords.accuracy,
            altitudeAccuracy: position.coords.altitudeAccuracy,
            heading: position.coords.heading,
            speed: position.coords.speed,
          },
          timestamp: position.timestamp,
        };
        success(geoPosition);
      },
      (_error) => {
        if (error) {
          error(_error);
        }
      },
      options
    );

    return watchId;
  }
  clearWatch(id: number): void {
    navigator.geolocation.clearWatch(id);
  }
}

const geo = new MyGeolocation();

geo.getCurrentPosition(
  (position) => {
    console.log("Current Position:", position);
  },
  (error) => {
    console.error("Position Error:", error);
  },
  { enableHighAccuracy: true }
);

const watchId = geo.watchPosition(
  (position) => {
    console.log("Watching Position:", position);
  },
  (error) => {
    console.error("Watching Position Error:", error);
  },
  { enableHighAccuracy: true }
);

geo.clearWatch(watchId);
profile
frontend, vuejs, react, docker, kubernetes

0개의 댓글