Front-End

vsoghlv@naver.com

Typescript 연습(interface, typealias)

interface

interface 는 간단히 말하면 class 또는 객체에 대한 타입을 지정할 때 사용된다.

interface Shape {
  getArea(): number;
}

class Circle implements Shape {
  //Shape interface 안에 있는 것들을 충족시키지 않으면 오류가 나옴
  getArea() {
    return 1;
  }
}

원넓이와 삼각형의 넓이를 구하는 클래스를 만들어보자.

interface Shape {
  getArea(): number;
}

//Shape interface 를 implements(클래스가 interface 에 있는 조건을 충족해야 한다.) 함
class Circle implements Shape {
  radius: number;
  //생성자
  constructor(radius: number) {
    this.radius = radius;
  }
  //Shape interface 안에 있는 것들을 충족시키지 않으면 오류가 나옴
  getArea() {
    return this.radius * this.radius * Math.PI;
  }
}

class Ractangle implements Shape {
  width: number;
  height: number;

  constructor(width: number, height: number) {
    this.width = width;
    this.height = height;
  }

  getArea() {
    return this.width * this.height;
  }
}

이제 만든 두 클래스를 사용해보자. 여기서 new 연산자를 사용해 새로운 인스턴스를 제작하는데 이때 타입은 클래스 타입으로 된다.

const circle = new Circle(5); //type = Circle 타입
const ractangle = new Ractangle(10, 5); //type = Ractangle타입

여기서 CircleRactangle 은 둘다 Shape 를 implements 하고 있기 때문에 아래와 같은 작업도 가능하다.

const shapes: Shape[] = [circle, ractangle];
//shapes 안에 있는 모든 도형들 넓이 추출하기
shapes.forEach((shape) => {
  console.log(shape.getArea());
});

위의 클래스들의 생성자를 보면 this.witdh = width 이런식으로 설정이 되어있는데 이는 private, public 등을 선언해주면 훨씬 짧게 사용할 수 있다.

class Circle implements Shape {
  //생성자
  constructor(public radius: number) {}
  //Shape interface 안에 있는 것들을 충족시키지 않으면 오류가 나옴
  getArea() {
    return this.radius * this.radius * Math.PI;
  }
}

class Ractangle implements Shape {
  constructor(private width: number, private height: number) {}

  getArea() {
    return this.width * this.height;
  }
}

둘의 차이는 외부에서 접근을 할 수 있느야 없느냐의 차이인데 컴파일하게되면 js 파일에서는 public 이든 private 이든 상관이 없다.

interface 로 객체타입 지정하기

interface 로 객체타입을 지정해 줄 수도 있다.

interface Person {
  name: string;
  //? 가 들어가게 되면 있을수도있고, 없을 수도 있음을 의미
  age?: number;
}

interface Developer {
  name: string;
  age?: number;
  skills: string[];
}

const person: Person = {
  name: "사람",
  age: 20,
};

const front: Developer = {
  name: "개발자",
  age: 29,
  skills: ["js", "React", "ts"],
};

만약 객체를 생성할 때 interface 에 설정해주지 않은 값을 넣거나, 설정한 값을 넣지 않을 경우 오류가 발생하게 된다.

위의 Person 과 Developer 을 보면 name 과 age 가 중복되는 것을 볼 수 있다. 이 문제는 상속을 통해 해결할 수 있다.

interface Person {
  name: string;
  //? 가 들어가게 되면 있을수도있고, 없을 수도 있음을 의미
  age?: number;
}
//Person 상속
interface Developer extends Person {
  skills: string[];
}

TypeAlias

TypeAlias 를 사용해 interface 와 비슷한 작업을 해줄 수 있다.

//interface 사용
interface Person {
  name: string;
  //? 가 들어가게 되면 있을수도있고, 없을 수도 있음을 의미
  age?: number;
}
//Person 상속
interface Developer extends Person {
  skills: string[];
}

//TypeAlias 사용
type Person = {
  name: string;
  //? 가 들어가게 되면 있을수도있고, 없을 수도 있음을 의미
  age?: number;
};
//Person 상속
type Developer = Person & {
  skills: string[];
};

TypeAlias 사용하면 interface 로 못하는 작업들을 몇 가지 할 수 있다. 하나 예롤 들자면 아래와 같은 작업을 할 수 있다.

type People = Person[];
const people: People = [person, front];

type Color = "red" | "blue" | "green";
const color: Color = "blue";

정리

객체를 사용할 때 왠만한 작업은 TypeAlias 를 사용해도 문제가 없다. interface 와 TypeAlias 중 더 편한 걸 사용하면 된다.

다만 몇가지 특이 케이스가 있는데

  • 만약 라이브러리를 위한 타입 설정 시 interface 사용 권장
  • 어떤 것을 사용하든지 일관성 있게 사용

타입스크립트를 공부하다가 느낀건데 .NET 을 사용할 때 공부했던 c# 이랑 매우 비슷한 것 같다. c# 과 자바스크립트가 합쳐진 느낌이다.