본문 바로가기
TypeScript/학습

TS 정리 (한 입 크기로 잘라먹는 타입스크립트(TypeScript)) - 05

by lms0806 2025. 5. 6.
728x90
반응형

해당 포스팅은 한 입 크기로 잘라먹는 타입스크립트(TypeScript)를 학습하면서 알게된 정보들을 정리하였습니다.

https://inf.run/EvrS5

 

한 입 크기로 잘라먹는 타입스크립트(TypeScript) 강의 | 이정환 Winterlood - 인프런

이정환 Winterlood | ,   프론트엔드의 피할 수 없는 대세 타입스크립트,이제는 제대로 정복할 때가 왔습니다! 😎 [사진]인프콘 2023 '타입스크립트는 왜 그럴까?' 발표자의 강의입니다.   🧐 배워

www.inflearn.com

 

JS 클래스

ts의 클래스에 대해서 배우기 이전에, js의 클래스에 대하여 간단하게 다뤄보고자 합니다.

 

js의 class 선언은 java와 비슷합니다.

class Student {
    // 필드
    name;
    grade;
    age;

    //생성자
    constructor(name, grade, age) {
        this.name = name;
        this.grade = grade;
        this.age = age;
    }

    //메서드
    study() {
        console.log("열심히 공부함");
    }

    introduce() {
        console.log(`안녕하세요 ${this.name} 입니다.`);
    }
}

java의 public Student와는 다르게 constructor를 선언하여, 생성자를 사용하게 됩니다.

 

만약 해당 클래스에서 특정 필드만 추가된 class를 사용하는 경우에는 어떻게 해야할까요?

 

class의 상속도 interface와 동일하게 extends를 활용하여 가능합니다.

class StudentDeveloper extends Student{
    // 필드
    favoriteSkill;

    //생성자
    constructor(name, grade, age, favoriteSkill){
        super(name, grade, age);
        this.favoriteSkill = favoriteSkill;
    }

    //메서드
    programming() {
        console.log(`${this.favoriteSkill}로 프로그래밍 함`)
    }
}

상속하는 경우, Student의 name, grade, age를 선언하지 않고도 사용할 수 있습니다.

 

단, constructor에서는 super()를 활용하여 Student의 생성자를 활용하게 됩니다.

 

class 선언하는 방식도 java와 동일하게 사용 가능합니다.

const studentDeveloper = new StudentDeveloper("홍길동", "A+", 29, "TypeScript");

TS 클래스

TS에서의 클래스는 JS의 클래스와 유사하게 작동합니다.

class Employee {
    //필드
    name;
    age;
    position;

    //생성자
    constructor(name: string, age: number, position: string) {
        this.name = name;
        this.age = age;
        this.position = position;
    }

    //메서드
    work() {
        console.log("일함");
    }
}

기존 js와 다른점으로는 생성자의 매개 변수에 타입이 추가되었다는 점입니다.

class Employee {
    //필드
    name;//error
    age;//error
    position;//.error
}

다음과 같이 사용하는 경우, 모든 필드에 error가 발생합니다.

 

이는 필드의 타입도 없고, default 값도 없기 때문에 발생합니다.

 

상속도 js와 마찬가지로 다음과 같이 활용이 가능합니다.

class ExecutiveOfficer extends Employee {
    //필드
    officeNumber;

    //생성자
    constructor(name: string, age: number, position: string, officeNumber: number) {
        super(name, age, position);
        this.officeNumber = officeNumber;
    }
}

ts에서의 class 사용방식은 다음과 같이 가능합니다.

const employeeB = new Employee("홍길동", 29, "developer");

또한 다음과 같은 방법으로도 활용 가능합니다.

const employeeC: Employee = {
    name: "홍길동",
    age: 29,
    position: "developer",
    work() { }
}

이렇게 사용하는 경우, class의 필드와 메서드를 모두 선언하여 사용하여야 합니다.

접근 제어자

ts에서의 접근 제어자로는 public, protected, private가 있습니다.

class Employee {
    //필드
    name;
    age;
    position;

    //생성자
    constructor(name: string, age: number, position: string) {
        this.name = name;
        this.age = age;
        this.position = position;
    }

    //메서드
    work() {
        console.log("일함");
    }
}

기본적으로 다음과 같이 선언된 class의 필드들은 모두 public 타입으로 선언되어져 있습니다.

 

그래서, 다음과 같이 외부에서 class를 선언하여 사용하는 경우 수정이 가능합니다.

const employee = new Employee("홍길동", 29, "developer");
employee.name = "홍길동2";
employee.age = 30;
employee.position = "디자이너"

외부에서 class의 필드를 읽거나 수정하지 못하도록 하기 위해서는 private나 protected를 사용하시면 됩니다.

 

protected를 사용하는 경우, 외부에서는 사용이 불가능하나, 해당 클래스를 상속받고 있는 파생 클래스는 해당 값을 사용할 수 있게 됩니다.

class Employee {
    //필드
    private name;
    protected age;
    public position;
}

상속하는 class의 필드 타입이 다음과 같을 때

class ExecutiveOfficer extends Employee {
    //필드
    officeNumber;

    //생성자
    constructor(name: string, age: number, position: string, officeNumber: number) {
        super(name, age, position);
        this.officeNumber = officeNumber;
    }

    //메서드
    func() {
        this.name; // error
        this.age;
    }
}

this.name은 private 타입으로 파생 클래스에서 사용할 수 없고, this.age는 protected 타입으로 파생 클래스에서 사용이 가능합니다.

 

표로 표현하면 다음과 같습니다.

접근 제어자 현재 클래스 파생 클래스 외부
public O O O
protected O O X
private O X X

 

이전에 선언한 Employee 클래스를 다음과 같이도 사용 가능합니다.

class Employee {
    //생성자
    constructor(private name: string, protected age: number, public position: string) {
    }

    //메서드
    work() {
        console.log("일함");
    }
}

매개 변수에 접근 제어자를 선언하는 경우, 생성자가 호출되면서 자동으로 필드를 생성하게 되고, 이를 입력받은 값으로 선언하게 됩니다.

인터페이스를 구현한 클래스

interface CharacterInterface {
    name: string,
    moveSpeed: number;
    move(): void;
}

다음과 같은 interface가 있다고 가정할 때, 이를 구현한 class는 어떻게 선언해야 할까요?

class Character implements CharacterInterface {} // error

다음과 같이 implements를 선언하여 가능합니다.

단, 다음과 같이 선언만 한 경우에는 CharacterInterface에 있는 필드나 메서드들이 Character에 없기 때문에 에러가 발생하게 됩니다.

class Character implements CharacterInterface {
    constructor(public name: string, public moveSpeed: number) { }

    move(): void {
        console.log(`${this.moveSpeed} 속도로 이동!`);
    }
}

다음과 같이 선언한 경우, 해당 에러는 제거되게 됩니다.

 

만약, 여기서 name이나 moveSpeed의 접근 제어자를 public에서 private이나 protected로 수정하게 된다면 어떻게 될까요?

 

그런 경우, interface는 public 타입만 허용하기 때문에, 접근 제어자에 대하여 에러가 발생하게 됩니다.

728x90
반응형

댓글