JiSoo's Devlog

[타입스크립트로 블록체인 만들기] Classes and interfaces 본문

Frontend/Typescript

[타입스크립트로 블록체인 만들기] Classes and interfaces

지숭숭숭 2024. 4. 17. 15:08

타입스크립트에서는 파라미터들을 써주기만 하면 알아서 constructor 함수를 만들어 준다

필드의 보호 등급, 이름, 타입만 써주면 된다

private 키워드는 오로지 타입스크립트가 우리를 보호해 주기 위해서만 사용한다

abstract class User {
  constructor (
    private firstName:string,
    private lastName:string,
    public nickname:string
  ) {}
  getFullName() {
    return `${this.firstName} ${this.lastName}`
  }
}

class Player extends User {
  
}

const jisoo = new Player("jisoo", "lim", "지수");


❌ jisoo.firstName
⭕ jisoo.nickname
⭕ jisoo.getFullName()

 

추상 클래스는 다른 클래스가 상속받을 수 있는 클래스로 직접 새로운 인스턴스를 만들 수는 없다

ex) new User(~~) X

 

추상 메소드를 만들려면 메소드를 클래스 안에서 구현하지 않으면 된다

메소드의 call signature만 적어둬야 한다

추상 메소드는 추상 클래스를 상속받는 모든 걸들이 구현해야 하는 메소드를 의미

abstract class User {
  constructor (
    private firstName:string,
    private lastName:string,
    private nickname:string
  ) {}
  abstract getNickName():void // 추상메서드
}

 

property를 private로 만든다면 그 클래스를 상속했을지라도 property에 접근 불가

만약 필드가 외부로부터는 보호되지만 다른 자식 클래스에서는 사용되기를 원한다면 protected 사용

 

class Workd {
  constructor(
    public readonly term: strin,
    public readonly def: string
  ) ( )
}

readonly 추가해 주면 내용 수정 불가

 

type

- 특정 값이나 객체의 값에 대한 타입 지정

- type alias 지정 가능

- 타입을 특정 값으로 제한 가능

type Player = {
  nickname: string,
  team: Team,
  health: Health
}

 

인터페이스는 오직 타입스크립트에게 객체의 형태를 설명해 주기 위한 용도로만 사용

interface Player {
  nickname: string,
  team: Team,
  health: Health
}
interface User {
  name: string
}
interface player extends User {
}
const jisoo : Player = {
  name:"jisoo"
}

 

type 키워드가 interface 키워드에 비해 좀 더 활용할 게 많다

interface User {
  name: string
}
interface User {
  lastName: string
}
interface User {
  health: number
}
const jisoo: User = {
  name: "jisoo",
  lastName: "l",
  health: 10
}

인터페이스는 동일한 이름으로 여러 번 선언이 가능하고 타입스크립트는 이 선언을 자동으로 병합한다

 

추상 클래스를 만들면 자바스크립트에서는 일반적인 클래스로 바뀌어버린다

인터페이스는 타입스크립트에서만 존재하기 때문에 컴파일하면 JS로 바뀌지 않고 사라진다

interface User {
  firstName: string,
  lastName: string,
  sayHi(name:string):string,
  fullName():string
}
interface Human {
  health: number
}
class Player implements User, Human {
  constructor(
    public firstName:string,
    public lastName:string,
    public health:number
  ){}
  fullName(){
    return `${this.firstName} ${this.fullName}`
  }
  sayHi(name:string){
    return `Hello ${name} My name is ${this.fullName(~~)}`
  
}

인터페이스를 상속하는 더 간단한 방법 -> implements

인터페이스를 상속할 때에는 property를 private로 만들지 못한다

인터페이스는 오브젝트의 모양을 결정지을 수도 있지만 클래스의 모양을 특정 짓기도 한다

인터페이스를 타입으로 지정하는 것도 가능, 인터페이스를 리턴도 가능(오브젝트 리턴)

 

타입을 상속하려면 ↓

type PlayerA = {
  name:string
}

type PlayerAA = PlayerA & {
  lastName:string
}

const playerA: PlayerAA = {
  name:"jisoo",
  lastName:"l"
}

 

인터페이스를 상속하려면 ↓

interface PlayerB {
  name:string
}

interface PlayerBB extends PlayerB {
  lastName:string
}

interface PlayerBB {
  health:number
}

const playerB: PlayerBB = {
  name:"jisoo",
  health:1
}

 

클래스는 인터페이스를 상속하기도 하고 타입을 상속할 수도 있다

 

다형성은 다른 모양의 코드를 가질 수 있게 해 주는 것

다형성을 이룰 수 있는 방법은 제네릭을 사용하는 것!

제네릭은 placeholder 타입을 쓸 수 있게 해 준다

interface SStorage{
  [key:string]:T
}

class LocalStorage{
  private storage:SStorage={}
  set(key:string,value:T){
    if(this.storage[key]!=undefined){
      console.log("Error: already exist!");
    }
    else{
      this.storage[key]=value;
    }
  }
  remove(key:string){
    delete this.storage[key];
  }
  get(key:string):T{
    if(this.storage[key]==undefined)
    {
      console.log("Error: Dosen't exist!");
      // return default;
      //자동으로 undefined가 반환되며 에러도 없음.
      //받는 쪽에서 undefined인지 검사할 필요가 있음.
     }
    return this.storage[key];
  }

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

const stringStorage=new LocalStorage();

console.log(stringStorage.get(""));
stringStorage.set("hello","How are you?");

const booleanStorage=new LocalStorage();
booleanStorage.get("xxx");
booleanStorage.set("ready?",true);

[key:string] : key가 제한되지 않은 오브젝트를 정의하게 해 준다

 

728x90