Typescript - interface, type

Angela_Hong·2023년 8월 7일

TypeScript

목록 보기
3/6
post-thumbnail

public이지만 수정이 불가능하도록 하고 싶으면?

  • readonly를 사용하면 된다
type Words = {
	[key:string]: string
}

class Dictionary{
	private words: Words
  	constructor(){
		this.words = {}
	}
  	add(word: Word){
		if(this.words[word.term] === undefined){
			this.words[word.term] = word.def;
		}
	}
  	// term을 사용해 word를 찾는 메소드
  	def(term: string){
		return this.words[term]
	}
  
  	static hello(){
		return "hello";
	}
}

class Word {
	constructor(
  		// readonly 기능을 사용
		public readonly term: string,
        public readonly def : string
	){}
}

const kimchi = new Word("kimchi", "한국의 음식")
const dict = new Dictionary()
dict.add(kimchi);
dict.def("kimchi")

Dict.hello() // static메소드

Interface 인터페이스

// 타입을 쓰는 첫번째 방법
type Player = {
  	// Player타입을 정의하는 방법
	nickname: string,
  	healthBar: number
}

const hong: Player = {
	nickname: "hong"
  	healthBar: 10
}

// 타입을 쓰는 두번째 방법
type Food = string;

const kimchi: Food = "delicious"
// 타입을 쓰는 세번째 방법 ( alias )
type Nickname = string
type HealthBar = number
type Friends = Array<string> 	// string의 배열

type Player = {
	nickname: string,
  	healthBar: number
}

const hong: Player = {
	nickname: Nickname
  	healthBar: HealthBar
}

키워드 type을 이용해 타입스크립트에서 만들고 싶은 무수히 많은 종류의 타입을 설명하면 된다

타입을 지정된 옵션으로만 제한하는 방법

type Team = "red" | "blue" | "yellow"
// 이렇게 concrete타입의 특정값들을 사용할 수 있다
type Health = 1 | 5 | 10

type Player = {
	nickname: string,
  	team: Team,		// team이 일반적인 string이 아닌 특정 string이 되도록 하는 방법
  	health: Health
}

const nico: Player = {
	nickname: "hong",
  	team: "yellow"
  	health: 10 
}

interface 방식

  • 객체 지향 프로그래밍의 개념을 활용해서 디자인되었다
  • 인터페이스는 한가지 특징을 가진다 : object의 모양/구조를 특정해주기 위한 것(type과 같다)
  • React.js 이용할때 많이 사용한다
type Team = "red" | "blue" | "yellow"
type Health = 1 | 5 | 10

interface Player {
  	// 인터페이스는 한가지 특징을 가짐 : object의 모양을 특정해주기 위함
	nickname: string,
  	team: Team,
  	health: Health
}

const nico: Player = {
	nickname: "hong",
  	team: "yellow"
  	health: 10 
}

타입스크립트에서 object 모양을 알려주는 방법 2가지

1) type Player = {}
2) interface Player{}

  • 차이점 : type키워드는 interface키워드에 비해 좀 더 활용할 수 있는게 많다
  • interface Hello = string 이건 불가능하다!!!

interface는 class와 비슷하다

//interface 사용
interface User {
	name: string
  	// readonly name: string 이것도 가능
}
interface Player extends User{
}

const hong : Player = {
	name: "hong"
}
// type 사용
type User = {
	name: string
}
type Player = User & {
}

const hong : Player = {
	name: "hong"
}

interface는 property들을 축적시킬 수 있다

interface User{
	name: string
}
interface User{
  	lastName: string
}
interface User{
	health: number
}

const hong: User = {
	name: "hong",
  	lastName: "yun",
  	health: 5
}
// interface를 3번 각각 만들어도 타입스크립트가 알아서 하나로 합쳐준다
// type으로는 할 수 없다

class, interface

User 추상클래스, Player 클래스

//	추상클래스는 이걸 상속받는 다른 클래스가 가질 property와 메소드를 지정하도록 해준다
// 만약 User클래스를 상속한다면, sayHi, fullName을 구현해야하고, firstName, lastName을 갖게 된다
// 상속받는 클래스가 어떻게 동작해야할지 일러주기 위해서 추상클래스를 사용한다
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}`
        // protected는 추상클래스롤부터 상속받은 클래스들이 property에 접근하도록 해준다
        // private를 쓰면 firstName, lastName을 Player가 접근할 수 없다
	}
  	sayHi(name: string){
		return `Hello ${name}. My name is ${this.fullName()}`
	}
}

추상클래스는 왜 사용할까?

  • 다른 클래스들이 표준화된 모양 표준화된 property와 메소드를 갖도록 해주는 청사진을 만들기 위해

인터페이스 방식

  • interface는 컴파일하면 js로 바뀌지 않고 사라진다
  • 클래스가 특정형태를 따르도록 강제하는 방법 implements
  • interface는 ts에만 존재한다
  • interface는 object모양을 특정짓기도 하지만, class모양을 특정짓기도 한다
  • 한 클래스에서 여러개의 인터페이스를 상속할 수 있다
interface User{
	firstName: string,
  	lastName: string,
  	sayHi(name: string): string,
  	fullName(): string
}
interface Human{
	health: number
}
class Player implements User, Human{ // 여러개를 한번에 상속받을 수 있다
  	// interface를 상속할때는 private,protected를 사용하지 못한다
  	// public이어야만 한다
	constructor(
		public firstName: string,
        public lastName: string,
        public health: number
	){}
  	fullName(){
		return `${this.firstName} ${this.lastName}`
	}
  	sayHi(name: string){
		return `Hello ${name}. My name is ${this.fullName()}`
	}
}

인터페이스를 타입으로 지정할 수도 있다

function makeUser(user: User){
	return "hi"
}
makeUser({   // argument에 인터페이스를 씀으로써 object모양을 지정해줄 수 있다
	firstName: "hong",
  	lastName: "yun",
  	fullName: () => "xx",
  	sayHi: (name) => "string"
}) // ()안에는 user를 넣어줘야한다 즉, 인터페이스를 타입으로 쓸 수 있다
// new User를 할 필요가 없이 interface의 내용물만 넣어주면 된다

클래스를 타입으로 쓸 수 있고, 인터페이스를 타입으로 쓸 수 있다


⭐️⭐️⭐️정리⭐️⭐️⭐️

인터페이스를 사용해 클래스에 특정 메소드나 property를 상속하도록 강제하는 방법을 배움
(인터페이스는 원하는 메소드와 property를 클래스가 가지도록 강제할 수 있게 해준다)
인터페이스는 자바스크립트로 컴파일 되지 않고 사라진다
추상클래스와 비슷한 보호를 제공하지만, 인터페이스는 js파일에서 보이지 않는다
추상클래스를 쓰면 js에서는 일반 클래스로 바뀐다

  • 파일 크기가 좀 더 커지고, 추가 클래스가 만들어진다는 의미
    만약 추상 클래스를 다른 클래스들이 특정 모양을 따르도록 하기 위한 용도로 사용한다면 같은 역할을 하는 인터페이스를 사용하는게 더 좋다
  • class Player extends User 대신 class Player implements User로 써줘야한다
  • 인터페이스가 js코드에서 보이지는 않는다

타입과 인터페이스 비교

첫번째, 타입을 쓰고 싶으면 type키워드를 사용하면 된다
type의 옵션은 object모양을 설명하는 것, 타입 alias를 만드는 것, 타입을 특정된 값으로 만드는 것
인터페이스와 비교할 내용은 object모양을 알려줄 때

공통점1 : object모양/구조를 알려주는 것

// ts에게 object모양을 알려주는 것이 목표
// 타입
type PlayerA = {
	name: string
}
const playerA : PlayerA = {
	name: "hong"
}
// 인터페이스
interface PlayerB{
	name: string
}
const playerB : PlayerB = {
	name: "hong"
}

둘의 목표는 같지만 타입과 인터페이스로 할 수 있는 것들이 조금 다르다

차이점 1: 상속하는 방법

  • 타입은 새 property를 추가하기 위해 다시 선언될 수 없지만, 인터페이스는 항상 상속이 가능하다
  • 만약 type에서 property를 하나 더 추가 하고 싶다고 하더라도 이름을 중복해서 사용할 수는 없다
    하지만 interface에서는 이름이 중복되더라도 사용을 할 수 있다.
type PlayerA = {
	name: string
}
type PlayerAA = PlayerA & {
	lastName: string
}
// type PlayerAA = {} 이렇게 추가하는 건 안된다
const playerA : PlayerAA = {
	name: "hong",
  	lastName: "xxx"
}
// 인터페이스
interface PlayerB{
	name: string
}
interface PlayerBB extends PlayerB{
	lastName: string
}
// interface에서는 이름이 중복되어도 가능하다
interface PlayerBB {
	health: number
}
const playerB : PlayerBB = {
	name: "hong",
  	lastName: "xxx"
}

공통점2: 타입과 인터페이스 모두 추상클래스를 대체해서 사용할 수 있다

type PlayerA = {
	firstName: string
}
interface PlayerB{
	firstName: string
}
class User implements PlayerA{
	constructor(
		public firstName: string
	){}
}
// 둘다 가능하다
class User implements PlayerB{
	constructor(
		public firstName: string
	){}
}

0개의 댓글