본문 바로가기
TypeScript

0062. TypeScript 공부하기11 - 클래스, 암묵적 Any 해결법, 접근제어자, 인터페이스와 클래스

by 보초코더^_^;; 2024. 2. 11.
반응형

섹션 6. 클래스

2강. 타입스크립트의 클래스

1) 암묵적 any 금지 - noImplicitAny 옵션 설정방법

이렇게 타입을 추론할 수 없을 때, any 타입으로 정의한다.

any 형식이 매우 위험한 타입이기 때문에 오류를 발생시키는 것이다.

 

  • 이때, tsconfig.json 파일에서 "noImplicitAny" 옵션을 false로 설정하면 에러가 사라진다.
    암시적 any를 허용하지 않을 것이냐? → false 이기 때문에 허용하라는 뜻이다.
  • 하지만, 이 옵션을 설정하면 암시적 any를 봐주기 때문에 타입스크립트를 사용하는 의미가 줄어든다.

그래서 원래 설정값이 꺼져 있으니 그대로 두거라, 옵션을 true로 설정하거나, 주석처리해서 없애는 게 좋고, 상황에 따라서 예외적으로 쓰는 것을 권장한다.

 

 

2) any 형식 지정 오류 해결법

형식 지정이 안되어서 형식을 지정해 주면 다른 오류가 발생한다.

이니셜라이져 : 초기값

초기값도 없고, 생성자도 없어서 undefined로 들어갈 건데 왜 썼냐? 는 에러임

 

(1) 해결방법 1 : 선택적 프로퍼티, 선택적 필드 (없어도 되는 값)

그렇게 좋은 방법은 아니다.


(2) 해결방법 2 : 기본 값을 넣어줌(빈 문자열 or 0)

 

(3) 해결방법 3 : 생성자를 만들어준다.

class Employee {
    //필드
    name
    level
    position

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

    //메서드
    work() {
        console.log("개발함ㅎ_ㅎ");
    }
}

const employeeB = new Employee ("초보코더", 5, "개발자");
console.log(employeeB);

 

3) 클래스, 타입으로 활용 - 타입 자동 추론

타입스크립트의 클래스는 실제 타입으로 활용된다.

Employee 타입이 생긴 것이고, 그래서 필드에 있는 name, level, position 프로퍼티, work() 매더스가 모두 들어 있어야 한다.

const employeeC: Employee = {
    name: "",
    level: 0,
    position: "",
    work() {},
};

 

4) 클래스의 확장

class Employee {
    //필드
    name
    level
    position

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

    //메서드
    work() {
        console.log("개발함ㅎ_ㅎ");
    }
}

class ExecutiveOfficer extends Employee {
    //필드
    officeNumber: number;
    //생성자
    constructor(
        name: string, 
        level: number, 
        position: string, 
        officeNumber: number
    ) {
        super(name, level, position);
        this.officeNumber = officeNumber;
    }
}

타입스크립트도 클래스의 확장이 가능하다.

 

 

3강. 접근제어자

접근제어자 : 클래스를 만들 때, 특정 특정 필드나 매서드에 접근할 수 있는 범위를 설정하는 문법

1) Public

기본값. 읽고 수정하는 것 다 가능하다.

 

객체에 접근하여 정보 수정이 가능하다. 

접근과 수정을 제한하지 않기 때문인데, 접근제어자는 기본값이 public으로 설정되어 있다.

 

2) Private

일반적으로 읽지도 못하고 수정도 안된다. readonly와 차이가 있다.

private에서 읽어오려면 매서드 안에서만 접근할 수가 있다.

파생 클래스에서도 접근할 수 없다.

class Employee {
    //메서드
    work() {
        console.log(`${this.level}입니다.`);
    }
}

매서드에서만 쓸 거면 private으로 설정하면 됨

 

 

3) Protected

외부에서는 접근 자체를 불가능하게 막지만 파생 클래스 내부에서는 그래도 접근할 수 있도록 해주는 제어자

public과 private의 중간쯤에 있는 접근제어자라고 생각하면 된다.

파생클래스 내에서는 접근할 수 있다.

 

생성자에 접근제어자를 사용하는 경우, 필드와 중복될 수 있기 때문에 필드를 삭제해야 한다.

 

접근제어자가 붙어있는 매개변수들은 자동으로 필드도 정의하고 필드의 값 초기화도 자동으로 한다.

this.name = name; 과 같은 작업을 하지 않아도 알아서 한다.

그래서 해당 부분을 삭제해도 오류가 나지 않는다.

 

 

4강. 인터페이스와 클래스

implements : 구현하다

class Character implements CharacterInterface {}

캐릭터 클래스는 캐릭터 인터페이스를 구현한다.

 

인터페이스 : 클래스의 설계도 역할

그래서 설계도대로 구현하지 않으면 에러가 발생함

 

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

class Character implements CharacterInterface {
    name: string;
    moveSpeed: number;

    constructor(name: string, moveSpeed: number) {
        this.name = name;
        this.moveSpeed = moveSpeed;
    }
    move() : void {
        console.log(`${this.moveSpeed} 속도로 이동!`);
    }
}

이렇게 설계도대로 하면 에러가 사라진다.

다만, 중복값이 많으니 접근제어자를 이용한다.

 

인터페이스에 정의하는 필드들은 무조건 퍼블릭으로만 정의할 수 있다.

그래서 private나 protected가 필요하다면 따로 정의를 해줘야 한다.

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

 

 

반응형